How create a function pointer to point a member function? [duplicate] - c++

This question already has answers here:
function pointer to a class member
(2 answers)
Closed 9 years ago.
Code:
struct A
{
void* f(void *)
{
}
};
int main()
{
void * (*fp)(void *);
fp = &A::f;
}
Compile:
|12|error: cannot convert 'void* (A::*)(void*)' to 'void* (*)(void*)' in assignment|
I have tried many ways, but all failed... How to do that?

For a regular member pointer, you'll need to declare the type it's a member of on the pointer type;
int main()
{
void * (A::*fp)(void *);
fp = &A::f;
}

Don't use function pointers use std::mem_fn
auto func = std::mem_fn(&A::f);
If you really want to use function pointers(you don't) you have to do this.
void * (A::*func)(void*);
func = &A::f;
IMO this is uglier, harder to read and less maintainable
You can also use std::function like this.
A a;
std::function<void*(const A &, void*)> f_add_display = &Foo::print_add;
but mem_fn is better suited for the job since you have a memfunction

std::function<void *( A&, void *)> fp = &A::f;

Related

type alias declaration for function pointer without parameters [duplicate]

This question already has answers here:
Function pointer to member function
(8 answers)
Closed 12 days ago.
From Cppreference - Type alias I know that following type alias declaration works:
using func = void (*) (int, int);
How does the equivalent for a function pointer to a class member look like?
You just need to add a qualifying class name before the *.
For example using func = void (foo::*)(int, int);
Demo :
struct foo
{
void bar(int, int);
};
using func = void (foo::*)(int, int);
func ptr = &foo::bar;

C++ and pointer to function of class [duplicate]

This question already has answers here:
How can I pass a member function where a free function is expected?
(9 answers)
Closed 2 months ago.
If I have two classes like this :
class A
{
public:
int *(*fun)( const int &t );
A( int *( *f )( const int &t ) ) : fun( f ) {}
};
class B
{
private:
float r;
int *f(const int &t)
{
return new int( int( r ) + t );
}
A a;
B() : a( A( f ) ) {}
};
This results in compiler error.
I want to assign f to a's function pointer.
The thing is that A can be used by many classes not just B so I can't simply define fun as B::*fun.
None of the posts I've found on the internet and here on stackoverflow address the issue of using the function pointers with many classes each having its own member function but the same prototype.
So what to do?
this result in compiler error
Because f is a A's non-static member function returning int*, that accepts single const reference to int. That means, that its type is not:
int* (*)(const int &);
but:
int* (A::*)(const int&);
Also, your code signalizes very bad design - I think you need simple virtual function. But if you want to keep writing things this way, you may want to read: ISOCPP: Pointers to members.
Remember, that non-static member functions of type C always accepts additional implicit argument of type C* (or const C*, if function is declared with const qualifier), that points to instance of C this function was called on.
Your code looks confusing and, personally, I believe that C function pointers look ugly on C++'s OO implementation. So I would advise you to use the std::function. It only has been available since C++11. If you cannot use it, try looking on Boost's Implementation.
I can give you an example of how to use the std::function:
bool MyFunction(int i)
{
return i > 0;
}
std::function<bool(int)> funcPointer = MyFunction;
Using this you will drastically improve your code reliability. As of your problem, specifically:
class A
{
public:
std::function<int*(const int&)> fun;
A(std::function<int*(const int&)> f) : fun(f) {}
};
class B
{
private:
float r;
int *f(const int &t)
{
return new int(int(r) + t);
}
A *a;
B()
{
std::function<int*(const int&)> tempFun = std::bind(&B::f, this, _1);
a = new A(tempFun);
}
};
You have to add the following namespace:
using namespace std::placeholders;
So what to do
Not much. Other than templating A on the type of objects for which it will hold a pointer to a member function taking a reference to a const int and returning a pointer to int.
What you're trying to do is to mix a pointer to a free function with a pointer to member function. Whilst it sounds like they're both function pointers they're different enough to not be able to pass through the same type definition.

std::function initialization for overloaded member function in a class [duplicate]

This question already has answers here:
How do I specify a pointer to an overloaded function?
(6 answers)
Closed 3 years ago.
How do we create a std::function object for overloaded member functions in a class? std::function object can be created for a non-overloaded member function as shown.
Sample code is attached as shown below
#include<iostream>
#include<functional>
class X
{
public:
X(){}
virtual ~X(){}
void foo1(char c)
{std::cout<<"X::foo1(char c)\n";}
void foo2(char c)
{std::cout<<"X::foo2(char c)\n";}
void foo2(int i)
{std::cout<<"X::foo2(int i)\n";}
}x;
int main()
{
std::function<void(X*,char)> f1=&X::foo1;
f1(&x,'a');
/* //The following code doesn't work
std::function<void(X*,char)> f2=&X::foo2;
f2(&x,'a');
*/
return 0;
}
Following error is given :
conversion from '' to non-scalar type 'std::function' requested
You need to be explicit about the signature of the overloaded function you intend to use:
std::function<void(X*,char)> f2 = static_cast<void (X::*)(char)>(&X::foo2);
As an alternative, use a lambda:
std::function<void(X*,char)> f3 =
[](X *instance, char c){ return instance->foo2(c); };

assign a member function to a function pointer [duplicate]

This question already has answers here:
How can I pass a member function where a free function is expected?
(9 answers)
Closed 2 months ago.
If I have two classes like this :
class A
{
public:
int *(*fun)( const int &t );
A( int *( *f )( const int &t ) ) : fun( f ) {}
};
class B
{
private:
float r;
int *f(const int &t)
{
return new int( int( r ) + t );
}
A a;
B() : a( A( f ) ) {}
};
This results in compiler error.
I want to assign f to a's function pointer.
The thing is that A can be used by many classes not just B so I can't simply define fun as B::*fun.
None of the posts I've found on the internet and here on stackoverflow address the issue of using the function pointers with many classes each having its own member function but the same prototype.
So what to do?
this result in compiler error
Because f is a A's non-static member function returning int*, that accepts single const reference to int. That means, that its type is not:
int* (*)(const int &);
but:
int* (A::*)(const int&);
Also, your code signalizes very bad design - I think you need simple virtual function. But if you want to keep writing things this way, you may want to read: ISOCPP: Pointers to members.
Remember, that non-static member functions of type C always accepts additional implicit argument of type C* (or const C*, if function is declared with const qualifier), that points to instance of C this function was called on.
Your code looks confusing and, personally, I believe that C function pointers look ugly on C++'s OO implementation. So I would advise you to use the std::function. It only has been available since C++11. If you cannot use it, try looking on Boost's Implementation.
I can give you an example of how to use the std::function:
bool MyFunction(int i)
{
return i > 0;
}
std::function<bool(int)> funcPointer = MyFunction;
Using this you will drastically improve your code reliability. As of your problem, specifically:
class A
{
public:
std::function<int*(const int&)> fun;
A(std::function<int*(const int&)> f) : fun(f) {}
};
class B
{
private:
float r;
int *f(const int &t)
{
return new int(int(r) + t);
}
A *a;
B()
{
std::function<int*(const int&)> tempFun = std::bind(&B::f, this, _1);
a = new A(tempFun);
}
};
You have to add the following namespace:
using namespace std::placeholders;
So what to do
Not much. Other than templating A on the type of objects for which it will hold a pointer to a member function taking a reference to a const int and returning a pointer to int.
What you're trying to do is to mix a pointer to a free function with a pointer to member function. Whilst it sounds like they're both function pointers they're different enough to not be able to pass through the same type definition.

C++ overloaded method pointer [duplicate]

This question already has answers here:
How do I specify a pointer to an overloaded function?
(6 answers)
Closed 7 years ago.
How do I get a method pointer to a particular overload of a method:
struct A {
void f();
void f(int);
void g();
};
I know that
&A::g
is a pointer to g. But how do I get a pointer to f or f(int)?
(void (A::*)()) &A::f
(void (A::*)(int)) &A::f
function pointers and member function pointers have this feature - the overload can be resolved by to what the result was assigned or cast.
If the functions are static, then you should treat them as ordinary functions:
(void (*)()) &A::f;
(void (*)(int)) &A::f;
or even
(void (*)()) A::f;
(void (*)(int)) A::f;
You just have to cast the result of &A::f in order to remove the ambiguity :
static_cast<void (A::*)()>(&A::f); // pointer to parameterless f
static_cast<void (A::*)(int)>(&A::f); // pointer to f which takes an int
Thanks to Stefan Pabst for the following idea, which he presented in a five minute lightning talk at ACCU 2015. I extended it with tag types to allow for resolving overloads by their cv qualifier and/or reference qualifier, and a C++17 variable template to avoid having to type the extra pair of parentheses which is otherwise required.
This solution works on the same principle as the cast-based answers, but you avoid having to restate either the return type of the function or, in the case of member functions, the name of the class which the function is a member of, as the compiler is able to deduce these things.
bool free_func(int, int) { return 42; }
char free_func(int, float) { return true; }
struct foo {
void mem_func(int) {}
void mem_func(int) const {}
void mem_func(long double) const {}
};
int main() {
auto f1 = underload<int, float>(free_func);
auto f2 = underload<long double>(&foo::mem_func);
auto f3 = underload<cv_none, int>(&foo::mem_func);
auto f4 = underload<cv_const, int>(&foo::mem_func);
}
The code implementing the underload template is here.