Binding function with argument as derived class - c++

I am trying to bind std::function with derived argument. Function I want to bind looks like this:
void Application::myFunction(Derived *derived) { }
Function I am trying to pass into this function (but bound) looks like this:
void Storage::register(int number, std::function<void(Base *base)>) { }
And I am doing this (this keyword in this context is Application):
myStorage->register(0, std::bind(&Application::myFunction, this, std::placeholders::_1);
But that gives me error:
error: no matching function for call (Storage::register...)
Any idea what am I doing wrong? Thank you!

This does not work because std::function<void(Base*)> does not guarantee that it will always be called with a Derived*. You cannot do this anymore than you can call Application::myFunction with a Base* directly.
Depending on what it is you want to achieve, make it a std::function<void(Derived *)> or have myFunction work with Base*.

Related

How do you call a function in a function using std::?

std::vector<char>function(std::string word) {
}
namespace::json getList(){
function();
}
I was just wondering if im suppose to call the function on top by including std::function(argument)
No, you don't need nor should you use the std::function class to call function. The std::function class is more like a function pointer wrapper. It lets you work with functions as data more easily.
For example, std::function<T> func represents some parameterless function that returns an object of type T.
Refer to the documentation for std::function for more information.

How to pass argument to std::bind to a function?

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.

C++ passing overloaded operator() of class as function pointer

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.

asio timer from other class

I try this : timer tuto.
But the void print is in another class. When i call the function in main:
t.async_wait(&class::print);
I have this error :
error : must use '.*' or '->*' to call pointer-to-member function in 'boost::asio::detail::lvref<void (class::*)(const boost::system::error_code&)>() (...)', e.g. '(... ->* boost::asio::detail::lvref<void (class::*)(const boost::system::error_code&)>())
I don't know how fix this issue :s
You will have to bind the object instance, like: t.async_wait(boost::bind(&Class::print, this, _1)); Or if the instance is not this, use another (smart) pointer that points to a Class. You can use a reference, but that requires a reference wrapper to prevent bind from copying the bound argument: Class c;
// ...
t.async_wait(boost::bind(&Class::print, boost::ref(c), _1));
I have already tried, but I have an error :
error : 'void (class::*)(const boost::system::error_code&)' is not a class, struct, or union type typedef typename F::result_type type;
You need to handle the parameter that the print method expects.
Something like this:
t->async_wait(boost::bind(&Class::print, this,
boost::asio::placeholders::error));
Take a look at this tutorial http://www.boost.org/doc/libs/1_59_0/doc/html/boost_asio/tutorial/tuttimer3.html
I try but I have an error which i don't understand
error : pointer to member type 'void (class::)(const boost::system::error_code&)' incompatible with object type 'windows'
BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1);
^
You will have to bind the object instance, like:
t.async_wait(boost::bind(&Class::print, this, _1));
Or if the instance is not this, use another (smart) pointer that points to a Class. You can use a reference, but that requires a reference wrapper to prevent bind from copying the bound argument:
Class c;
// ...
t.async_wait(boost::bind(&Class::print, boost::ref(c), _1));
You need to handle the parameter that the print method expects.
Something like this:
t->async_wait(boost::bind(&Class::print, this,
boost::asio::placeholders::error));
Take a look at this tutorial http://www.boost.org/doc/libs/1_59_0/doc/html/boost_asio/tutorial/tuttimer3.html

c++ using method as parameters to functions

I don't understand why the following code compile and works:
template<typename Predicate>
void foo(Predicate p) {
}
bool g(int n) {
}
void user(int n) {
foo(g);
}
foo is supposed to get a function object that will run on a data structure but I made the method simpler, because what I don't understand is how can this works? A method isn't an object. The normal way to do it is to create a new class, override operator() and then send an instance of that class.
Well, in this case the Predicate parameter is substituted by a function pointer of type bool (*func) (int). Nothing wrong with that...
The Predicate template argument can be almost any type. So you can use it for function pointers and classes as well as the basic types.
If you use the function argument p as a function, then it can be anything that is callable, like a function pointer, an object whose class have an operator() member function, a pointer to a static member function, a std::bind object, a std::function object or a lambda expression.
It can't be a pointer to a member function though, because to call a pointer to a member function you need an instance to call it on. For this use std::bind.