For several reasons, I must use a struct defined in an extern C lib. I have simplified my code in order to make it readable.
Struct defined in C Lib
extern "C" {
typedef struct {
double (*_function)(double x);
} FuncR;
}
Cpp file containing class A
Class A {
public:
A();
void foo(double x); // Cannot be static since it uses m
void bar();
private:
double m; // non-static member by nature
};
void A::bar() {
FuncR f;
f._function = &A::foo;
};
The call f._function = &A::foo; generates the following error :
error C2440 : '=' : cannot convert from 'double (__thiscall A::*)(double)' to 'double(__cdecl*)(double)'
I have been searching for answers and apparently foomust be declared static. In my case it is not possible since it has to use non-static members...
Is there any trick to solve my problem ?
No, I don't think there's a trick to "fix" this.
The method call needs a this pointer, which the function pointer can't handle.
Often you can define a static "trampoline" function to get you into a method, but that requires that the outer layers (the C code, in this case) supports passing around e.g. a void * where you can store the this pointer.
Does the FuncR struct really need to be defined/used in C code? Can you use C++-style member function pointers?
How about this?...
class A;
struct classA_MemberFuncR {
double(A::*_function)(double);
};
class A {
public:
A() : m(1.234) {};
double foo(double x) {
std::cout << "In foo(" << x << "): this="
<< (void*)this << ", m=" << m << '\n';
return m+x;
}
void bar();
private:
double m; // non-static member by nature
};
void A::bar() {
classA_MemberFuncR fm;
fm._function = &A::foo;
double result = (this->*fm._function)(4.321);
std::cout << "Result is: " << result << std::endl;
};
[Comment added at this point:] Dang. Re-read OP's original post. (Supposedly we're stuck with the C struct's non-member function pointer.)
Hmm. On GCC I tried a whole lot of casting combinations and it never let me cast M::foo's address to much of anything else, so I wrote a runtime cast function template to force it to allow me to cast anything at all to any other type I want without complaining (Everyone: Please hold off on the screams of "that's not portable!" Sure it's portable... It's just how you use it that may or may not be portable!):
/*---- In a header file somewhere... ----*/
#include <stdarg.h>
template <typename ToTy, typename FromTy>
ToTy forceCast_helper(int dummy, ...);
template <typename ToTy, typename FromTy>
inline ToTy forceCast(FromTy obj) {
// ...has nothing to do with Star Wars!
return forceCast_helper<ToTy,FromTy>(1, obj);
}
/*---- In a source file somewhere... ----*/
template <typename ToTy, typename FromTy>
ToTy forceCast_helper(int dummy, ...) {
va_list args;
va_start(args, dummy);
ToTy ret = va_arg(args, ToTy);
va_end(args);
return ret;
}
Which allowed me to compile the following code without error:
typedef double(*doubleFuncDouble_t)(double);
typedef double(A::*doubleClassAMemberfuncDouble_t)(double);
f._function = forceCast<doubleFuncDouble_t>(&A::foo);
// and then call this->foo(4.321) with it from within A::bar() as follows...
(this->*(forceCast<doubleClassAMemberfuncDouble_t>(f._function)))(4.321);
Unfortunately when it ran, it segfaulted. Further investigation shows that, at least on GCC for 32-bit Linux for x86, sizeof(a member function pointer) is 8, while sizeof(a nonmember function pointer) is 4. When I changed the type of FuncR::_function to uint64_t, amazingly, the call succeeded. (I was surprised as well.)
So it seems regardless of any casting magic you might find that compiles without error, there's really no way at all you'd ever be able to squeeze a member function pointer into a nonmember function pointer, at least on GCC for 32-bit x86. And even if you could, that doesn't encapsulate the 'this' pointer, as 'unwind' mentioned in his post.
I think there's still hope, though.
unwind's post suggests a trampoline function but concedes that it would require separately passing the 'this' pointer & managing that in the C code as a void*. I'm assuming your C library is not modifiable? If so, you should still be able to do a trampoline without being able to pass a 'this' pointer through it, assuming you have a limited number of such function pointers you'll need to be specifying:
You could create an array of class A object pointers, sized to however many of these FuncR function pointer objects you'll be using:
A* arrayThatHoldsAObjPointers[8]; // assuming you only need 8 such FuncR func ptr objects
Then create that many physical static nonmember functions (each conveniently named with a suffix number corresponding with its associated array index), and in the body of each, make them call A::foo() via its associated 'A' object in the arrayThatHoldsAObjPointers:
double trampoline_0(double d) { return arrayThatHoldsAObjPointers[0]->foo(d); }
double trampoline_1(double d) { return arrayThatHoldsAObjPointers[1]->foo(d); }
...and so on...
Then when you need to set a FuncR object for use by your C library, give it the address of one of the trampolines, and at the same time, store the pointer to that A object in the associated arrayThatHoldsAObjPointers[] element. To make the code that sets these easier to use, you could also create an array of function pointers to the trampolines.
Related
Imagine the following situation
You have a pointer to a variable: fooVar *
You can get the type of the variable with a function like this: get_type(fooVar* foo) which is returning a int value bar
You can then lookup in an enum to which type the returned value bar belongs, e.g. 1 -> type_int
Depending on the type, you can then call one of the following functions to get the value: double get_double(fooVar*), int get_int(fooVar*), ...
The goal is
To wrap those functions (which is a simplified version of a C library) into a CPP class.
The problem is
I would like to store a list of all Variables.
How to return the current value of the variable in a uniform way?
I tried to create a BaseType and derive the other types from it, like that:
BaseClass
|--> IntClass - int getValue()
|--> DoubleClass - double getValue()
'--> BoolClass - bool getValue()
I could then create a member function .getValue() for each derived class with the correct return type (as shown above).
Since I am storing pointers to all Variables in a list of Type BaseClass*, my compiler is now complaining that getValue() is not defined when I am trying to call it.
A second solution might be to create double getAsDouble(), bool getAsBool(), int getAsInt() and then throw an error if the type is not convertible or if it doesn't fit. But that feels wrong, too.
A third solution might be to not only store the pointer but also the type it points to (of the derived class). Later on I could then cast the BasePointer. But it it really a good idea?
Another solution might involve std::variant, but I think that's overkill - right?
The Question is: How would you do that in C++? Is there a clean way to achieve that?
Sidenote: None of the topics I've read here on SO really fits, it feels like a standard problem to me so I would like to learn some ways professional programmers solve this kind of issue.
It seems like you have gotten yourself into the corner of trying to re-implement virtual functions and dynamic inheritance.
So, perhaps the most straightforward thing you could do is have a virtual BaseType::getValue() function, which is overridden by the subclass-specific getValue().
But these days, we try to avoid arrays of raw pointers - that requires explicit allocation and de-allocation, and is error prone (e.g. - what happens if you throw an exception?). At the very least, make it something like an std::vector<std::unique_ptr<BaseType>> (or std::shared_ptr instead of std::unique_ptr). If you haven't heard about these pointer-like classes, read this:
What is a smart pointer and when should I use one?
Beyond that - if you know the set of possible types in advance, and its not huge - then, as you yourself suggested - an std::variant may be a reasonable choice. Variants in C++ are a bit unwieldy, but they're very safe; and one you get used to them, they're convenient enough. So, in your case:
using foo_var = std::variant<IntClass, DoubleClass, BoolClass>;
//...
auto foo_vars = get_array_of_foo_vars_somehow();
for(const foo_var& : foo_vars) {
your_complex_visit([]auto&& arg) {
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, int>)
std::cout << "int with value " << arg << '\n';
else if constexpr (std::is_same_v<T, double>)
std::cout << "double with value " << arg << '\n';
else if constexpr (std::is_same_v<T, bool>)
std::cout << "bool with value " << arg << '\n';
else
static_assert(always_false_v<T>, "non-exhaustive visitor!");
}, foo_var);
}
// Note: No need to `free()` anything when the array goes out of scope
Now, your_complex_visit() is a bit like std::visit(), except that you look at arg.getValue() intead of just args(). Or you can use std::visit in the above, but would need to change the types to the outer ones (IntClass instead of 'int' etc.)
A second solution might be to create double getAsDouble(), bool getAsBool(), int getAsInt() and then throw an error if the type is not convertible or if it doesn't fit. But that feels wrong, too.
A alteranative approach to throwing an exception in case of error could be to return std::optional<double>, std::optional<bool> and std::optional<int> for getAsDouble(), getAsBool() and getAsInt(), respectively. This way, returning an empty std::option would then signal a failure – i.e., there is no such a value to retrieve – that isn't an error.
For example, if you had the following declarations corresponding to the C code:
struct FooVar;
int get_type(const FooVar*);
int get_int(const FooVar*);
double get_double(const FooVar*);
#define INT_TYPE 1
#define DOUBLE_TYPE 2
You could write a wrapper class that contains user-defined conversion operators to FooVar * and const FooVar *:
class FooVarWrapper {
FooVar *ptr_;
public:
// ...
operator FooVar*() noexcept { return ptr_; }
operator const FooVar*() const noexcept { return ptr_; }
// ...
};
Note that thanks to the conversion operators, you can still use the C API directly with this wrapper class, e.g., you can call your original function get_type() with a FooVarWrapper object as an argument because this will be implicitly converted into the stored FooVar *.
Then, you can define those getter functions as non-member functions as well:
std::optional<int> getAsInt(const FooVarWrapper& obj) {
if (INT_TYPE != get_type(obj))
return std::nullopt;
return get_int(obj);
}
std::optional<double> getAsDouble(const FooVarWrapper& obj) {
if (DOUBLE_TYPE != get_type(obj))
return std::nullopt;
return get_double(obj);
}
// ... similarly for getAsBool()
However, you may want to consider marking the conversions operators as explicit to avoid easily bypassing these functions that return std::optional by calling get_int() or get_double() directly. This way, you will need to write static_cast<> whenever you want to convert a FooVarWrapper object into the stored pointer; the conversion won't occur implicitly.
the question is how to get pointer to self inside method of a class without touching this:
class Foo
{
int a, b, c;
void Print();
};
This way in common compiler I can do this refering to first data field:
void Foo::Print()
{
cout << &a; // == this
}
But are there any ways to do this without data members when only function exists?
class Foo2
{
void Print();
};
p.s. don't even ask me why do I need this :)
For a POD class with at least one data member, the address of the class-type object is the same as the address of its first data member. This is because there can be no unnamed padding bytes before the first data member of a POD struct type. [In C++11, the rules are a bit different; I believe that this is true for all standard layout class types. I am not entirely familiar with the rules, however.]
For any other class type, there is no way to do this.
class Foo2
{
void Print();
};
#define OBJADDR(x) (th##x##s)
void Foo2::Print()
{
int i; // red herring, but the name MUST be `i`
std::cout << OBJADDR(i);
i; // to get rid of compiler warning about unused local variable
};
If your class has no data members then technically, instances of the class don't even exist. For convenience only, they are required to have size of at least 1 byte and have unique this pointers. If you inherit from a class with no data members, its size collapses to 0 and it disappears.
So no, there isn't any way to get the this pointer without using the this pointer. A less pragmatic version of C++ wouldn't even have this pointers for these objects, as they would have size 0.
You can probably hack it using the offsetof macro
void Foo::Print()
{
cout << static_cast<char *>(&a) - offsetof(Foo, a);
}
if you can't safely assume &a is the start.
So ... why do you need to do this?
Whilst digging through the STL sources (DinkumWare, SGI, STLport, etc..) and trying to make sense of their implementation choices (it's going well), I came across something I feel is a bit odd or rather ive never run into before.
Generally when one wishes to overload a member function in a derived class, you would prepend the base class member function signature with the virtual keyword, however at various points in the STL source this is not the case.
Here is a cut-down version of what I'm seeing in the STL implementations:
template <typename T> class A {
public:
void func( ) { std::cout << "inside A func( )" << std::endl; }
};
template <typename T> class B : public A<T> {
public:
void func( ) { std::cout << "inside B func( )" << std::endl; }
};
The compiler seems fine with this pseudo-polymorphism, where as I was expecting an error something along the lines of:
error C2535: 'void B<T>::func(void)': member function already defined or declared
Would someone be kind enough to explain what is going on here?
PS: This also seems to work without the classes being templates too.
'Regards
Without the virtual keyword - when redefining a function, you are hiding the super's function.
In your case, by redifining func(), you tell the compiler there is a new function for B, which is different from A's.
Though, because it is not declared virtual, you will see this affect only if you invoke func() from a variable of type B. A variable of type A which holds a B, will invoke A's func().
A *a = new B;
a->func()
will invoke the first [A's] method.
To invoke B's method, you need the type to be B:
B *b = new B;
b->func()
The B<T>::func member simply shadows A<T>::func. When you call p->func() where A<T> *p points to a B<T>, A<T>::func is called, so there's no polymorphism.
#include <iostream>
struct A
{
void func() { std::cout << "Hello!\n"; }
};
struct B : public A
{
void func() { std::cout << "Goodbye!\n"; }
};
int main()
{
B b;
A *p = &b;
p->func();
b.func();
}
(Demo)
In the C++ standard, there's at least one place where this shadowing/name hiding is exploited: std::ifstream::rdbuf hides its ancestor's method by that name and actually changes its return type.
There clearly is no error because these functions are just overloads: A::func() has a signature taking an A object (a reference or a pointer) as first argument while B::func() has a signature taking a B object as first argument. That is, this is just overloading of two functions with different argument but the function name.
This is done in a few places to produce a different return type from a function which is essentially trivially forwarding to another function (at least, these are the places I can think of). This is just to make life a bit easier for users although it is actually more confusing than anything else. The examples I can think of (e.g. the rdbuf() function in streams) should have created a different name instead.
This is acceptable code, B<T>::func is just hiding A<T>::func.
A<int> a;
B<int> b;
a.func(); // inside A
b.func(); // inside B
A<int> *const pA = new B<int>();
pA->func(); // inside A
When calling func through a polymorphic type, it will call the function on the type of the pointer.
I have 2 classes
class B {
public:
int func(int i);
};
class A {
public:
typedef int (B::*fPtr)(int);
void run();
B* mB;
};
void A::run() {
// create a pointer
fPtr p = &(B::func);
// invoke the function
mB->*p(2); <------- Compilation Error
}
What i need is to create a pointer to func() in A's run function. I get a compilation error saying that mB is not corresponding to a function with 1 argument.
please help
You need to put parentheses around the function expression:
(mB->*p)(2);
But as others have pointed out, there's almost certainly a better way to do what you're trying to do.
Instance methods on a class always have a hidden first parameter for the this pointer, thus it is incompatible with your function pointer typedef. There is no way directly to obtain a pointer to a member function. The typical workaround is to use a "thunk" where you pass a static function that accepts a generic "catch all" parameter (such as void *) which can be statically cast to a pointer of your choosing on which you can invoke the member function. Example:
class B
{
public:
static void MyThunk(void * obj)
{
static_cast<B *>(obj)->MyRealFunc();
}
void MyRealFunc()
{
// do something here
}
// . . .
};
You can get a pointer to the static function easily as it has no 'hidden this', just reference it using B::MyThunk. If your function requires additional parameters, you can use something like a functor to capture the necesssary parameters and state.
You should definitely read this C++ FAQ Lite page which tells you much more about all this: Pointers to member functions
why can you not call mB->func(2);?
If you need different functions for B perhaps look into virtual functions and class inheritance
Is void* necessary apart from memory allocation related stuff in C++?
Can you give me an example?
Logging memory addresses
If you want to output a pointer using iostreams (e.g. for logging) then going via void* is the only way of ensuring operator<< hasn't been overloaded in some crazy way.
#include <iostream>
struct foo {
};
std::ostream& operator<<(std::ostream& out, foo*) {
return out<<"it's a trap!";
}
int main() {
foo bar;
foo *ptr = &bar;
std::cout << ptr << std::endl;
std::cout << static_cast<void*>(ptr) << std::endl;
}
Testing iostream status
iostreams overload operator void* as a status check so that syntax like if (stream) or while (stream) is a short hand way of testing the stream status.
Template meta programming
You might want to use void* with template metaprogramming sometimes as a reduced catch all, e.g. with SFINAE tricks, but more often than not there's a nicer way around it using a partial specialisation of one form or another.
Accessing most derived pointer
As Alf pointed out in the comments dynamic_cast<void*> is also useful for getting at the most derived type in a heirarchy, e.g.:
#include <iostream>
struct other {
virtual void func() = 0;
int c;
};
struct foo {
virtual void func() { std::cout << "foo" << std::endl; }
int a;
};
struct bar : foo, other {
virtual void func() { std::cout << "bar" << std::endl; }
int b;
};
namespace {
void f(foo *ptr) {
ptr->func();
std::cout << ptr << std::endl;
std::cout << dynamic_cast<void*>(ptr) << std::endl;
}
void g(other *ptr) {
ptr->func();
std::cout << ptr << std::endl;
std::cout << dynamic_cast<void*>(ptr) << std::endl;
}
}
int main() {
foo a;
bar b;
f(&a);
f(&b);
g(&b);
}
Gives:
foo
0xbfb815f8
0xbfb815f8
bar
0xbfb815e4
0xbfb815e4
bar
0xbfb815ec
0xbfb815e4
On my system.
Exceptions
§ 15.3.1 states:
The exception-declaration shall not denote a pointer or reference to
an incomplete type, other than void*, const void*, volatile void*, or
const volatile void*.
So it seems to be the only legal way of catching a pointer to an incomplete type is via void*. (Although I think there's possibly bigger issues if you actually needed to use that)
Legacy C uses
There are a lot of "legacy" C uses for void* for storing pointers to data without knowing what it is, but in new C++ code there is almost always a better way of expressing the same functionality.
No it isn't. It's only an idiom to refer to non typed memory
external libraries use them often (esp. in C).
in this case, i'll usually hide the use of these libraries (or the more dangerous portions). i hide them by writing interfaces around them (like wrapping). the interfaces i write serve to introduce type safety into the program. in this case, void* may be required, but at least it's hidden and restricted to a method or callback.
void* is frequently used for callbacks.
Callbacks are generally implemented in the C language using function
pointers and auxiliary user-defined data passed as a void pointer for
genericity.
[from here]
Of course, this is not type-safe, so people come up with ways to wrap this kind of thing, like here.
One situation where you might want to use void is when passing around data buffers, such as in this function:
void loadData(void* data, std::size_t size)
A lot of code passes buffers through a char-pointer instead of a void-pointer because, typically, buffers are read in 1 byte chunks, which happens to be the size that the C++ standard ensures a char to have.
However, using void-pointers is more generic. It's a way for the function to tell you, "Just give me some data, don't worry about how I'll read it". The function can then cast the pointer and read the data in chunks or whatever size it likes.
void * is used in C++ to express a pointer type to an unknown structure.
So I would use it whenever I have a pointer type where the code shouldn't know what is in there:
memory allocation
containers
...
Often void * mix quite well with template code to avoid template induced code bloat.
imagine you implement a
template <typename T>
class vector {
/*stuff */
};
you can then create a template specialisation for T * which uses void pointers so the code doesn't get duplicated.