Troubles with pointer to methods - c++

I'm just learning C++ and I'm having difficulties regarding pointers to methods. Lets say:
class One {
public:
int Add (int a, int b) {return a+b;}
};
typedef int (One::*pAdd) (int, int);
class Other {
public:
int Next (pAdd funct, int c){ return funct (c, 1);}
};
int main (){
One one;
Other other;
other.Next(one.Add, 2);
return 0;
}
I have a number of problems, as reported by my MinGW. First, I'm not invoking funct correctly, as compiler insists on using .* or ->* . Have no idea how to incorporate this request and any help is welcomed. Now, I could solve my problems by making methods static to use c-style pointers or pass objects and invoke methods from within Next, but I want to understand pointers to methods. Basically, I'm puzzled why one.Add is not an acceptable input. Method to call is unambiguously defined (.Add) and conforms my typedef. Also, I'm providing instance of class (one) from typedef thus providing context in which method is to be executed. But compiler output looks like I didn't only miss the syntax, but like I missed the concept. So, how to pass pointer to method with object as context as a single argument?

The main problem here is that member functions are not associated with an object instance, they are just function pointers with a slightly different signature.
So, when you want to call a member function you need two things: a pointer to the member function and the object instance in which to call it.
I changed your code sample a bit:
#include <iostream>
class One {
public:
int Add (int a, int b) {return a+b;}
};
typedef int (One::*pAdd) (int, int);
class Other {
public:
int Next (One one, pAdd funct, int c){
return (one.*funct)(c, 1);
}
};
int main (){
One one;
Other other;
std::cout << other.Next(one, &One::Add, 2) << std::endl;
return 0;
}
And it works now. It can probably be improved a bit, but I think you can take it from here.
I recommend that you read Pointers to member functions section of the c++ faq lite, which explains this very well.

So, how to pass pointer to method with object as context as a single argument?
Using just member-function pointers, you can't. Although your syntax looks like something that should do that, it just isn't allowed. You need an object to apply the function to:
class Other {
public:
int Next (pAdd funct, One & o, int c){ return (o.*funct) (c, 1);}
}
int main (){
One one;
Other other;
other.Next(&One::Add, one, 2);
}
If you want to create a function object that calls a particular member function of a particular object, then one possibility is to use std::bind (or boost::bind if you can't use C++11 yet):
#include <functional>
class Other {
public:
int Next (std::function<int(int,int)> funct, int c){ return funct (c, 1);}
};
int main (){
One one;
Other other;
using namespace std::placeholders;
other.Next(std::bind(&One::Add, &one, _1, _2), 2);
}
or a lambda:
other.Next([&](int a, int b){return one.Add(a,b);}, 2);

Pointers to members need an instance to operate on. Essentially, they are functions which take an addition parameter which becomes the implicit this pointer. To call a function through a pointer to member for the current object you can use code like this:
(this->*funct)(c, 1);
(you'd access member variables similarly but without a function call).
The object you call the member on isn't part of the pointer to member. As a result you need to get it something like this:
&One::Add
This becomes more interesting if the member function is overloaded: in this case you need to provide a context from which the overload can be determined when taking the address. I tupically use a static_cast<>() for this:
static_cast<int (One::*)(int,int)>(&One::Add)

You have a bunch of problems here: one.Add is a member function and
you cannot just invoke it. You need to have a pointer to the class to
invoke it on as well. Also, you need to use the special operator.*
or operator->*. You can also not take the address of a bound member
function.
All in all, you should use a template and boost/std::bind to make
all this bearable or stay away from it.
Here is modified, working code:
class One {
public:
int Add (int a, int b) {return a+b;}
};
typedef int (One::*pAdd) (int, int);
class Other {
public:
int Next (One* one, pAdd funct, int c){ return (one->*funct)(c, 1);}
};
int main (){
One one;
Other other;
other.Next(&one, &One::Add, 2);
return 0;
}

Related

How to use a static method as a callback in c++

I have a comparison/ordering function that relates to a class. I can use it if I define it as a separate closure object. I would like to make it into a static method of the class it operates on so it is tidier. I guessed how to do this but I get an error that I can't interpret.
Generally I would like to know how to treat static methods as callable objects.
Minimal related example code (not working):
#include <set>
class MyClass {
// More code here
static auto compare(MyClass a, MyClass b) {
return a < b;
}
};
int main() {
std::set<MyClass, decltype(MyClass::compare)> s(MyClass::compare);
return 0;
}
Update, I'm not sure if my example confused the issue, so I updated it.
Couple of issues:
compare is private, make it public.
One must use & to get the address of functions.
#include <set>
class MyClass {
public:
static auto compare(int a, int b) {
return a < b;
}
};
int main() {
std::set<int, decltype(&MyClass::compare)> s(&MyClass::compare);
return 0;
}
Make the function public, and add & in decltype:
std::set<int, decltype(&MyClass::compare)>
I wouldn't consider this to be "tidier" though.
A functor occupies 0 bytes when used as a std::set comparator. But a function pointer (as in your example) occupies 4 or 8 bytes. It also forces you to pass the function to the set's constructor.
Using a function pointer this way only makes sense if you want to switch between different comparators at runtime.
If you do want a pointer, the class itself is unnecessary. You might as well use a free function.

Get the name of an overloaded function passed as an argument at run-time

Assume all includes are defined, please go through the code structure defined below.
std::unordered_map<std::string, void*> callbackReg;
class A
{
public:
void foo(int a)
{
//impl
}
void foo(int a, int b)
{
//impl
}
void foo(int a, double d)
{
//impl
}
};
template<class Instance , typename Function>
void register_func(Instance& obj, Function func)
{
/* have to store function name as the key and
- pointer to raw member function pointer as the value,
- in callbackReg Map */
// ---> Point B
}
int main(int argc, const char * argv[])
{
A a;
register_evt(a, &A::foo); //---> point A
system("Pause");
}
Problems and Discussions
# Point A how to resolve function name scope resolution issue which means how to call a overloaded function/pointer to such function ? without inline static cast since it makes bit ugly and messy.
# Point B assume we have fixed overload name resolutuin issue and now we have to store member funtion name and its pointer value in callbackReg map.
I know may this could bad cumbersome approach but, is this feasible in C++? or else is there any way to store raw memeber funtion pointers with some other key-value in order to use them as callbacks.Since at debug time,debugger already knows what is the function name passed as register_func template fucntion argument.
Please look at the image attached.
Therefore,simply, how can we implement callback register/unregister scenario using only raw member/non-member function pointers?
(Please if the solution or methodology is a cross-platform approach that would be grateful, at least Win32 based)
You can use boost backtrace:
boost::stacktrace::frame provides information about functions. You may construct that class from function pointer and get the function name at runtime

Function pointer with specific argument list

Fairly simple question:
I have a class that uses a (variable) heuristic function to perform a certain algorithm. This heuristic function should ideally be fed to the class constructor as some sort of pointer and implement the following declaration:
int heuristic_Function(GridLocation a, GridLocation b);
What is the best way to accomplish this? Ideally I would like to avoid additional classes and keep the code fairly self-contained (and yes, I am aware of things like delegates and the strategy pattern).
(This has probably been asked hundreds of times already but in different terms)
Well, as you said, you could store a function pointer:
struct Algo
{
using HeurFn = int(GridLocation, GridLocation);
Algo(HeurFn * heuristic) : heuristic_(heuristic) {}
void Run()
{
// use "heuristic_(a, b)"
}
HeurFn * heuristic_;
};
Then instantiate it:
extern int my_fn(GridLocation, GridLocation);
Algo algo(my_fn);
algo.Run();
An alternative would be to pass the function directly to Run, in which case you could make Run a template and perhaps allow for inlining of the actual heuristic code, but you explicitly asked for the heuristic to be configured via the constructor.
Instead of old C function pointer, I would recommend std::function.
So you could write it like this
#include <functional>
struct algorithm{
algorithm (std::function<int(GridLocation, GridLocation)> heuristic_function) :
heuristic(heuristic_function) {}
int do_something (GridLocation a, GridLocation b){
return heuristic(a,b);
}
private:
std::function<int(GridLocation, GridLocation)> heuristic;
}
Advantages are the better readable syntax, and that the caller can use std::bind expressions.
Or you could just take the heuristic as a template, but then you would to either make your algorithm to just a function or write the type to every new instance. See https://stackoverflow.com/a/2156899/3537677
Things get really simple if only the method that does the computations needs the function, and you can forgo storing the function in the class itself. You can then parametrize the method on the type of the passed function, and you get full flexibility:
struct Calculate {
template <typename F> int run(F && f) {
return f(1, 2);
}
};
int f1(int, int) { return 0; }
struct F2 {
int operator()(int, int) { return 0; }
};
int main() {
Calculate calc;
// pass a C function pointer
calc.run(f1);
// pass a C++98 functor
calc.run(F2());
// pass a C++11 stateless lambda
calc.run(+[](int a, int b) -> int { return a-b; });
// pass a C++11 stateful lambda
int k = 8;
calc.run([k](int a, int b) -> int { return a*b+k; });
}
You don't need to manually spell out any types, and you can pass function-like objects that can be stateful.
The power of C++11 comes from the && syntax. There's more to it than meets the eye. In run's parameter, F is a deduced type, and && is a universal reference. That means that, depending on the context, it acts either as an lvalue-reference we know from C++98, or as an rvalue-reference.
The + operator applied to the lambda stresses that it is in fact stateless. Its uses forces a conversion from the abstract lambda type to a C function pointer. The type of the +[](int,int)->int {...} expression is int(*)(int,int). The use of the + operator is not necessary, I've only used it to underline the statelessness.

How to pass method of a class into another function in C++?

Say I have a class and a function
class A
{
int a;
int b;
int mul()
{
return a+b;
}
};
...
void func(int af, int bf, int (*fc)())
{
...
}
In the main function, the function is supposed to use the methods of class A
int main
{
A as;
...
func(as.a, as.b, as.mul);
}
However, I can't do that, the compiler keeps telling me that I'm passing
(int&, int&, 'unresolved overloaded function type')
into a function of candidate
(int, int, void(*)()).
Why is that, and how to pass method of a class into another function?
Oh, I think I should make the problem a little bit clearer. func(...) is actually a function from an algorithm I'm working on. And class A is a model that will use the algorithm to do the simulation. So I don't think I'll specifically use the instance of A in function B, but only pass A's methods and components in and work with them.
Update: Some have mentioned using static methods in class A. However, this is still a partial solution. Using static method mul() will force me to claim a and b both to be static. And if I have to use multiple instances of A, with method a, b different in each instance in my main function, using static variables will simply fail.
So, are there other suggestions on how to fix this without using static variables/methods? I remember in script languages such as python, passing methods of whatever type is basically not an issue. Why can't I do a similar thing in C++? Or are there workarounds in C++ that can help me do this?
First of all, mul is a member function of A, so you can't invoke it as if it was a global function or a static member function: it needs an object on which the function is invoked:
A::mul(); // ERROR!
A a;
a.mul(); // OK
This said, you could change the definition of func to accept a pointer-to-member-function:
void func(int af, int bf, void (A::*fc)())
// ^^^^^^^^^^^^^^^
However, this change alone won't make you progress too much, because you're still not passing the concrete instance of A on which the member function should be invoked. In other words, this would be illegal:
fc(); // ERROR!
To over come this limitation, you could pass a reference or a pointer to an instance of A together to func, and call it as done below:
void func(A* pA, int af, int bf, void (A::*fc)())
{
...
(pA->*func)();
}
However, if func() has the object on which the member function should be invoked passed in as an argument, it is not clear what is the purpose of af and bf.
Possibly, if your mul() member function does not need to work on any concrete instance of A, and still you want to make it a member of A, you could declare it as static:
class A
{
int a;
int b;
static void mul();
// ^^^^^^
};
This would make your original call to func() compile. However, in this case it is not clear whether this would make sense, since the fact that mul() accept no arguments suggests that it is supposed to work on the a and b members of the object it is invoked on.
Is mul indended to be a non-static member, needing an object of type A to invoke it on? In that case, you'll need to pass a pointer-to-member:
void func(int af, int bf, void (A::*fc)())
{ // ^^^
A a = whatever();
(a.*fc)();
}
If it's intended to be called without an object, then it needs to be static.
What you want to do is to pass a member function pointer (A::mul) along with the instance (a) itself. That's not that easy without any additional code.
Member function pointers aren't tied to an instance (they only represent the function itself, not the instance on which to be called on). Their type is described together with the class name. The type of a member function pointer on A with the signature of your func will look like this:
void (A::*)() // The type only, anonymous
void (A::*fc)() // An actual function pointer with the name `fc`
To call such a function, you have to use the following syntax, in which, as you can see, the instance to call the function on, has to be involved:
(a->*fc)(); // If a is of type A*
(a.*fc)(); // If a is of type A or A&
To put things together, you have basically two options.
Also pass the instance (as a pointer, a reference, either const or modifiable) in addition to a member function pointer. Then, call the member function pointer on that instance.
You're function's signature and implementation will then look like this:
void func(int af, int bf, void (A::*fc)(), A *a) {
// When you want to call the function fc on a:
(a->*fc)();
}
To call func, use a code like this:
func(as.a, as.b, &A::mul, a);
Convert the member function pointer together with the instance to a functor which can be called as is. This can be best done with std::mem_fn together with std::bind1st.
You're function's signature and implementation will then look like this:
void func(int af, int bf, std::function<void()> fc) {
// When you want to call the function fc:
fc();
}
To call func, use a code like this:
func(as.a, as.b, std::bind1st(std::mem_fn(&A::mul), a));
If you really want to treat int (*fc)(int,int) (void return and empty parameter list given in another example) as a regular function pointer (I mean not function pointer to class member function), You can do the following to use the function of A and pass it into func. The point is to declare mul as static member function. I am assuming very simple operation like multiplication.
#include <iostream>
class A
{
public: //necessary otherwise not accessible in main
int a;
int b;
A(int p1, int p2):a(p1),b(p2){} //assume you need to somehow pass a,b into mul
static int mul(int p1, int p2) {return p1*p2;}; //mul should be static
};
void func(int af, int bf, int (*fc)(int,int))
//using void still work but you need to change declaration of mul in A
{
int res = fc(af,bf);
cout << res <<endl;
}
int main()
{
A as(2,4);
func(as.a, as.b, &A::mul); //call A::mul, use as regular function pointer, output 8
func(10,10, &A::mul); //will output 100
return 0;
}
This way you are using the static member function of A that can be pointed to by a regular function pointer. It has nothing to do as a and b inside the class anymore.
As leemes said, you can do this with std::function which is what I would recommend as well, but check out what your compiler has support for, and if so, you can use a single call to std::bind and have it work. Example below that works on Visual Studio 2012 (and should work on newer versions of GCC with the flag for C++11 enabled, and may or may not work on VS 2010)
void func(int af, int bf, std::function<void()> fc)
{
fc();
}
call with:
func(as.a, as.b, std::bind(&as::mul, &A));
The newer versions of std::bind do the std::mem_fcn part for you if it detects a member function. See the doc linked here:
std::function
std::bind

Misunderstanding function pointer - passing it as an argument

I want to pass a member function of class A to class B via a function pointer as argument. Please advise whether this road is leading somewhere and help me fill the pothole.
#include <iostream>
using namespace std;
class A{
public:
int dosomeA(int x){
cout<< "doing some A to "<<x <<endl;
return(0);
}
};
class B{
public:
B(int (*ptr)(int)){ptr(0);};
};
int main()
{
A a;
int (*APtr)(int)=&A::dosomeA;
B b(APtr);
return 0;
}
This brilliant piece of code leaves me with the compiler error:
cannot convert int (A::*)(int)' toint (*)(int)' in initialization
Firstly I want it to compile.
Secondly I don't want dosomeA to be STATIC.
Pointers to members are different from normal function pointers. As the compiler error indicates the type of &A::dosomeA is actually int (A::*)(int) and not int (*)(int).
Inside B's constructor you need an instance of A to call the member on using one the .* or ->* operators.
E.g'
B(int(A::*ptr)(int))
{
A atmp;
(atmp.*ptr)(int);
}
http://www.parashift.com/c++-faq-lite/pointers-to-members.html
You don't have a pointer to a function that returns an int and takes an int. You have a pointer to a member-function that returns an int and takes an A* and an int. Not only do you need to fix the type of your pointer, B needs to provide an A* to serve as dosomeA's this parameter.
Boost::bind has some functionality meant to simplify using function pointers in general, and they provide support for pointers to member functions. See here.