I'm having problems with passing a class pointer as a parameter in a lambdas callback.
pastebin: http://pastebin.com/SqXHtGDt
How I define the callback:
typedef void (*cb_prescription)(Prescription * prescription);
How I use the callback:
void loop_prescriptions (cb_prescription callback, bool add = true)
{
for (int i = 1; i <= prescriptions->noOfElements(); i++) {
Prescription * prescription = (Prescription *) prescriptions->removeNo(i);
if (add) {
prescriptions->add(prescription);
}
callback(prescription);
}
}
I know that everything works, except the parameter pointer part.
loop_prescriptions ([&] (Prescription * paper) { paper->something(); });
The error I'm getting:
error: cannot convert ‘list_prescriptions_by_doctor()::’ to ‘cb_prescription {aka void ()(Prescription*)}’ for argument ‘1’ to ‘void loop_prescriptions(cb_prescription, bool)’
});*
Does anyone know how I'm using the parameter incorrectly?
I've tried to add a reference for the pointer as *&, and just removing the pointer, but the List class (yes I must use this) returns a class pointer, so I cannot simply use a copy.
Thanks for any help!
UPDATE
I've updated my pastebin based on the answer, which gives a working solution.
http://pastebin.com/7yTPGEQx
Your function only accepts function pointers, while you are passing a lambda (or in other words, any random class). Since classes aren't function pointers, most likely would like to accept functors (e.g. Everything which is function like)
I guess you can change your code in 2 different ways:
// Using a std::function object; which wraps both function pointers and classes with () operator
using cb_prescription = std::function<void(Prescription*)>;
or
template<typename cb_prescription>
void loop_prescriptions (cb_prescription &&callback, bool add = true)
The first variant is the one that I would prefer, as this is very generic, unfortunately it comes with a performance overhead from wrapping the callback. Unless you are in performance critical code, I would use this one.
The second variant works via templates, so whatever you pass there that can be called with () operator and matching arguments will work. However it requires this code to be available for all callers. Due to the the template, the exact type of the function-ptr, lambda is known, so you will not get the overhead from the std::function.
Related
I have the following code which used std::bind :
EventListenerCustom* _createNewObjectlistener =
eventDispatcher->addCustomEventListener(Constants::MY_EVENT,
std::bind(&MyClass::MyFunction, this, std::placeholders::_1));
It seems I create many different kinds of object listeners, where the only difference is the event, and the function being called. If I wanted to encapsulate the above code into a function:
How would I pass MyClass::MyFunction as an argument to the function ?
What would the function signature and parameters look like ?
I imagine the function would look something like this:
EventListenerCustom* MyFunc(<What Goes Here> functionToBeBound,<What goes here> object,std::string EVENT){
EventListenerCustom* eventListener = eventDispatcher->addCustomEventListener(EVENT, std::bind(functionToBeBound, object, std::placeholders::_1));
return eventListener;
}
What should the function look like ? And How do I call it? What would the calling code look like?
EDIT: Concrete details:
I have many listener objects which are created in identical ways:
auto eventDispatcher = _dragNode->getEventDispatcher();
_createNewObjectlistener = eventDispatcher->addCustomEventListener(Constants::MY_EVENT, std::bind(&MyClass::myOtherFunction, this, std::placeholders::_1));
_moveNewObjectlistener = eventDispatcher->addCustomEventListener(Constants::MY_EVENT2 std::bind(&MyClass::myFunction, this, std::placeholders::_1));
Constants::MY_EVENT etc are just const char* .
The only difference is the Function being called, and the string constant used as an event name. How can I encapsulate this into a function ? I have tried John Zwinck's solution below, but for some reason I can't get it to compile because the compiler complains:
: No viable conversion from '__bind<void (*&)(cocos2d::EventCustom *), MyNameSpace::MyClass *, const std::__1::placeholders::__ph<1> &>' to 'const std::function<void (EventCustom *)>'
To make it simpler, create a typedef for a pointer to any member function in MyClass which has the appropriate signature:
typedef void (MyClass::*MyMemberFn)(int); // replace int and void as needed
Then:
EventListenerCustom* MyFunc(MyMemberFn functionToBeBound, MyClass* object, std::string EVENT){
return eventDispatcher->addCustomEventListener(EVENT, std::bind(functionToBeBound, object, std::placeholders::_1));
}
What you're really looking for is std::function. The documentation for such is here: https://en.cppreference.com/w/cpp/utility/functional/function
Their example is really good at explaining how it's used, but for your case (or related) try this:
std::function<void(int)> func1 = std::bind(MyClass::MyFunction, this, std::placeholders::_1));
What this will do is create an object which can be called, and the first argument is forwarded on to the first argument of the member function, both of which should be int type, and it returns nothing. You don't actually need address-of operator for the function name.
The cool part here is that the object returned by std::bind can be passed into the constructor of std::function and all its information is preserved. So when you need a concrete type that can be copied and all that cool stuff (passed into a function NOT by reference for example) then use a std::function as it will do the job, as long as it's not trying to copy a non-copyable type or something. std::function can also be initialized with a function pointer. It's generally just "better" than function pointers for C++, especially combined with std::bind to handle classes.
I could write out more examples, but check out the link above, and check out std::bind on that same website. Both should help.
So I got myself onto shaky ground by insisting on making a C++ class immitate a regular function. The class overloads the function operator, making it a functor, of course. This all works fine, until you want to pass the function pointer of this functor.
Naturally, I want to let the compiler know that we know what we're doing (lol), by doing a reinterpret_cast of this pointer. However, how do I get the address of this particular member function, since it is an overloaded operator. How does one get the address of that?
UPDATE: You asked for an example. Here is a minimal one.
So I have an interface, which I cannot change. It looks like this;
typedef void (*some_callback_t)(SomeType);'
void someFunc(some_callback_t);
Now, this is quite straight-forward; the API is setting some callback function pointer. So, the idea was to implement the callback as a functor class, by overloading the operator(), like so, as usual.
class Bah {
void operator()(SomeType);
};
Here comes the question; seeing as I cannot change the API used (the function that expects a function pointer of a certain signature), how can I then get the address of the member function and pass that?
I suspect it goes something like;
someFunc(reinterpet_cast<some_callback_t>( ? ? ? )); to make sure that the compiler won't barf at me.
Supposing that you have to use a function pointer, and that your functor has no state, you can use a lambda as glue:
void takesFunctionPointer(void (*)());
struct MyFunctor {
void operator()();
};
// ...
takesFunctionPointer([] { return MyFunctor{}(); });
How does one get the address of that?
In the same way as any other member function. The name of the function is class_name::operator(). An example:
struct class_name {
void operator()(){}
};
void (class_name::*member_function_pointer)() = &class_name::operator();
class_name instance;
(instance.*member_function_pointer)(); // in a block scope
Naturally, I want to let the compiler know that we know what we're doing (lol), by doing a reinterpret_cast of this pointer.
That's usually not what one would want to do.
I have the following class:
class conditionStack : public Stack
{
public:
bool even(int);
bool odd(int);
bool positive(int);
void push(bool(*)(int), int);
};
push function:
void conditionStack::push(bool (*p)(int), int a)
{
if (p(a))
Stack::push(a);
}
I call function in main.cpp in the following way
conditionStack Even;
Even.push(Even.even, value);
But as a result a have the following error
error C3867: 'conditionStack::even': function call missing argument list; use '&conditionStack::even' to create a pointer to member
I tried to call it as Even.push(&conditionStack::even, value); But it doesn't work :( Could you help me?
Function pointers that also contain information about the object instance are called delegates and were long time no standard feature in C++.
Since C++ 11 there is std::function.
You should have a look at it:
http://en.cppreference.com/w/cpp/utility/functional/function
One of the examples shows what you want:
// store a call to a member function
std::function<void(const Foo&, int)> f_add_display = &Foo::print_add;
const Foo foo(314159);
f_add_display(foo, 1);
A C++ member function takes an invisible extra argument (this) which makes taking a pointer to it as above a bit more tricky.
The slightly old school way to handle them is "mem_fun"
The boost way to make it more friendly is "boost::bind"
The slightly modern way to handle them is to "C++ lambda"
Suffice to say, however, that a member function is probably of the type:
bool (*) (conditionStack *, int)
and I bet you could make that work if you really really wanted to, but as comments have suggested, please don't. It's not standard, not guaranteed, and not readable!
Alternatively, you could try making them all static member functions (static functions don't take a this argument).
A comment said I lack examples. This is true. An example could have got quite large and complex and the question isn't well enough defined to justify it (yet). There is an example of storing a vector of lambdas here : Why can't I create a vector of lambda in C++11?
I'm creating an application with a class that has a number of animation methods. I need these animation methods to be called in a random way. So, my idea was to create a vector of void function pointers, and iterate through the vector. I can't get it to compile though. I'm getting the error: "invalid use of void expression".
Applicable code:
.h
std::vector<void(*)(int,float)> animationsVector;
void setAnimations();
void circleAnimation01(int circleGroup, float time);
.cpp
polygonCluster01::polygonCluster01()
{
setAnimations();
}
void polygonCluster01::setAnimations()
{
animationsVector.push_back(circleAnimation01(1,2.0)); //error is here
}
void polygonCluster01::circleAnimation01(int circleGroup, float animLength)
{
//other code
}
I've followed some other posts here which suggest I'm doing it right, but it still won't compile, and I'm not sure why.
polygonCluster01::circleAnimation01 is not a free-standing function, but a member function. Thus, you need a member function pointer to store its adress. Here is the type you're looking for :
std::vector<void(polygonCluster01::*)(int,float)> animationsVector;
// ^^^^^^^^^^^^^^^^^^
Edit: let's complete this answer.
When you give the correct type to your vector, it still won't compile. This is because, as stated by crashmstr, function pointers and member function pointers are just that - a pointer to a (member) function. In particular, they can't store parameters for later use, which you are trying to do.
So what you actually need is not a mere (member) function pointer, but something that can wrap a function and some parameters to call it later.
Well, C++11 has you covered ! Take a look at std::function. It's a type-erased container, designed to do just what is written above. You can use it like this :
std::vector<std::function<void(polygonCluster01*)>> animationsVector;
...
animationsVector.push_back(std::bind(
&polygonCluster01::circleAnimation01, // Grab the member function pointer
std::placeholders::_1, // Don't give a caller for now
1, 2.0 // Here are the arguments for the later call
));
...
animationsVector[0](this); // Call the function upon ourselves
Your vector contains function pointers, not the result of the function you are calling in there.
animationsVector.push_back(circleAnimation01(1,2.0));
Use this instead
animationsVector.push_back(circleAnimation01);
The invalid use of void expression that you are getting is because you are trying to store the result of the circleAnimation01 function call which is void instead of a pointer to a function that returns void upon receiving an int and a float.
Also, as Quentin has stated, you need them to be functions, not member functions, either change the signature of the vector or change those members to free functions.
I'm having some trouble creating a static wrapper function using template parameters. I don't want to pass the function directly to the wrapper function, because it needs a specific signature int (lua_State *) so that it can be passed into the following function:
lua_pushcfunction(L, function);
(That's right, I'm going for an auto-generated lua wrapper.)
My first thought is to create a template function with a function pointer as a non-type template argument.
template <void(* f)(void)>
int luaCaller(lua_State * _luaState)
{
f();
return 0;
}
So far, this is looking pretty good. This function has the proper signature, and calls a function I pass in via template argument.
&(luaCaller<myFunc>)
My problem arises when I try to wrap this in another function. Non-type template parameters must be externally linked, and thus the following fails:
void pushFunction(lua_State * _luaState, void(* _f)(void))
{
lua_pushcfunction(_luaState, &(luaCaller<_f>));
}
Which makes sense, because the address of the function needs to be known at compile time. You can't throw in just any pointer and expect the compiler to know which classes to create. Unfortunately, if I add a function pointer that is known at compile time it still fails. The value of the function pointer is being copied into _a, and therefore _a is still technically not known at compile time. Because of this, I would expect the following to work:
void pushFunction(lua_State * _luaState, void(* const _f)(void))
{
lua_pushcfunction(_luaState, &(luaCaller<_f>));
}
or maybe
void pushFunction(lua_State * _luaState, void(* & _f)(void))
{
lua_pushcfunction(_luaState, &(luaCaller<_f>));
}
In the first case, because the value isn't allowed to change, we know that if it is externally linked, it will still technically be externally linked. In the second case it's being passed in as a reference, which would mean it should have the same linkage, no? But neither of these attempts work. Why? Is it possible to circumvent this somehow? How can I cleanly auto generate a function that calls another function?
The const qualifier means you aren't allowed to change something, not that it's a compile-time constant. The initial value of _a is determined at runtime when the function is called, and for a * const &a, the value can even change at runtime by some external means such as another thread, if the object underlying the reference is not const.
To make the fully templated wrapper work, you need to give the compiler enough information to compile a function for each possible template argument, and provide logic to switch among those functions. The template system generates and organizes related functions, but it's not a dynamic dispatcher.
If you can add the function pointer to the lua_State object and eliminate the template parameter, that would be one solution.
Your solution would work if make the function pointer a template argument to doCaller, but that would defeat its purpose.
Rather than using a non-type function-template approach in order to bind the secondary function you want to call inside the wrapper-function, you could use a struct with a static luaCaller method. That should allow you to maintain the function signature you need for passing luaCaller to lua_pushcfunction.
So for instance, you could have a struct that looks something like the following:
template<void (*f) void>
struct wrapper
{
static int luaCaller(lua_State * _luaState)
{
f();
return 0;
}
};
template<typename Functor>
void doCaller(lua_State * _luaState, Functor wrapper)
{
Functor::luaCaller(_luaState);
}
then call it like:
doCaller(&luaState, wrapper<my_func>());