C++ callback with lambda function - c++

First of all, I'm beginner in C++ so I don't know if the way I'm doing this is right or can cause some problem.
So, I'm trying to pass a generic callback to a function and then call member functions from different objects inside that callback. In this case, I'm creating a closure with a lambda function to capture the objects and then inside the lambda I'm calling they member functions.
Well, for example, the code is something like this:
// ...
void functionWithCallback(std::function<void()> callback)
{
// Do some stuff ...
callback();
}
int main()
{
SomeClass some_object = SomeClass();
AnotherClass another_object = AnotherClass();
std::function<void()> callback = [&some_object, &another_object]() {
some_object.someFunction();
another_object.anotherFunction();
};
functionWithCallback(callback);
}
My question is: is this a correct way or can it cause some problems or unexpected behaviors? Is there any more elegant way to do this?

Related

passing an argument to a boost::thread constructer [duplicate]

So I have done some research, and have found you can create a boost::thread object and have it start with a non-static class function by using "this" and boost::bind etc. It really doesn't make much sense to me and all the examples I could find had the boost::thread object launched within the same class as the function it was starting with so this could be used. I however, am launching the thread in a different class so I'm afraid by using "this", I will be saying the "this" is from the class I am creating the thread from, rather than the one the function is in (I'm probably wrong, I need to learn more about this "this" guy). Here is an example of my source I am having the problem with.
ANNGUI.h
class ANNGUI
{
private:
boost::thread *GUIThread;
Main *GUIMain;
public:
// Creates the entire GUI and all sub-parts.
int CreateGUI();
}
ANNGUI.cpp
int ANNGUI::CreateGUI()
{
GUIMain = new Main();
GUIThread = new boost::thread(GUIMain->MainThreadFunc);
};
This isn't all the source, but I think my problem is in here somewhere, I know I have to deal with the "this" somehow, but I'm unsure how. I Could use a static function, but I didn't really want to make my variables static either.
Thanks.
Also, Is there any very good resource for using any boost libraries? Their web site documentation seems good, but over my head.
The this keyword is used with boost::bind when the function object you're creating is bound to a object member function. Member functions can't exist apart from instances, so when creating a functor object out of a member function with boost::bind, you need a pointer to an instance. That's exactly what the this keyword actually is. If you use the this keyword within a member function of a class, what you get is a pointer to the current instance of that class.
If you were to call bind from outside a class member function, you might say something like:
int main()
{
Foo f;
boost::thread* thr = new boost::thread(boost::bind(&Foo::some_function, &f));
}
Here, we're using Foo::some_function as our thread function. But we can't use this because we're calling bind from main. But the same thing could be achieved using this if we called bind from within a member function of Foo, like so:
void Foo::func1()
{
boost::thread* thr = new boost::thread(boost::bind(&Foo::some_function, this));
}
If a member function is static, or is simply a regular (non-member) function, then you don't need an instance pointer at all. You would just do:
boost::thread* thr = new boost::thread(some_regular_function);
As others mentioned, when you want to call an object method in a new thread, you have to supply the address of that object. But you don't need to call boost::bind, you can use the overloaded boost::thread constructor like this:
GUIThread = new boost::thread(&Main::MainThreadFunc, GUIMain);
If the method is in the same class you use this to get the address of the current instance, e.g.:
t = new boost::thread(&myclass::compute, this);
If the method has parameters, you can specify them after the second argument, e.g.:
t = new boost::thread(&myclass::compute, this, p1, p2);
boost::bind is your friend (it can sometimes have a rough way of showing it though)!
use GUIThread = new boost::thread(boost::bind(&Main::MainThreadFunc, GUIMain));
and then make your MainThreadFunc a regular member. That means that you can use the instance variables directly like you would normally do.
Something like this:
class GUIMain {
public:
GUIMain() : m_Member(42) {}
void MainThreadFunc() {
// use all members as you would normally do
std::cout << m_Member << std::endl;
}
private:
int m_Member;
};
In cases like this it is useful to think of non-static member functions as free functions that take the this as first parameter, for example in your case void MainThreadFunc(Main* this).
boost::thread accepts a nullary functor, so you have to pass it a nullary functor which contains a reference to the instance GUIMain and calls GUIMain->MainThreadFunc which, seen as I explained above, would be something like MainThreadFunc(GUIMain).
Boost (and now also C++ with TR1) provides helpers to create such functors, namely boost::bind (or alternatively boost::lambda::bind). The expression boost::bind(f, arg1, arg2, ...) means "return a nullary functor which calls f(arg1, arg2, ...)".
That said, you can use the following expression to create the thread:
GUIThread = new boost::thread(boost::bind(&Main::MainThreadFunc, GUIMain))
If your object is a functor, i.e. has an operator(), you can pass an instance of it to boost::thread. The operator() does not need to be static. For example:
#include <boost/thread.hpp>
struct th {
void operator()();
};
void th::operator()()
{
for (;;) {
// stuff
}
}
int main()
{
th t;
boost::thread my_thread( t ); // takes a copy of t !
my_thread.join(); // blocks
return 0;
}

Pass class function to another class function

sorry for possible duplicates, but I didn't understand the examples and codes snippets I found.
I have a class named "EncoderWrapper" which includes some functions. One of these functions is called "onAfterTouch" and is declared in the "EncoderWrapper.h" file.
void onAfterTouch(byte channel, byte pressure);
The functions will become a callback for another class function of a library I use
inline void setHandleAfterTouch(void (*fptr)(uint8_t channel, uint8_t pressure)) {
usb_midi_handleAfterTouch = fptr;
};
Note: I'm totally new to C++, so I want to say sorry if I'm doing some "no-gos" or mixing up some terms.
The question is: How can I pass my class function (member function?) to that "setHandleAfterTouch" function of the library?
This won't work:
void EncoderWrapper::attachMIDIEvents()
{
usbMIDI.setHandleAfterTouch(&EncoderWrapper::onAfterTouch);
}
... my IDE says
no matching function for call usb_midi_class:setHandleAfterTouch(void (EncoderWrapper::*)(byte, byte))
I've also tried
usbMIDI.setHandleAfterTouch((&this->onAfterTouch));
But this won't work ... and I don't get the approach on that.
Every Help is very appreciated ;-)
Function pointer and member function pointer have different types. You can it for yourself:
struct Test {
void fun();
};
int main() {
void(*ptr)() = &Test::fun; // error!
}
Instead, member function pointer need this syntax:
void(Test::*fun)() = &Test::fun; // works!
Why you ask? Because member function need an instance to be called with. And calling that function have a special syntax too:
Test t;
(t.*funptr)();
To accept member function pointer, you'll need to change your code to this:
inline void setHandleAfterTouch(void(EncodeWrapper::*fptr)(uint8_t, uint8_t)) {
usb_midi_handleAfterTouch = fptr;
};
Since it's rather limiting accepting only the functions from one class, I recommend using std::function:
inline void setHandleAfterTouch(std::function<void(uint8_t, uint8_t)> fptr) {
usb_midi_handleAfterTouch = std::move(fptr);
};
This will allow you to send lambda with captures, and call your member function insode it:
// we capture this to use member function inside
// v---
usbMIDI.setHandleAfterTouch([this](uint8_t, channel, uint8_t pressure) {
onAfterTouch(channel, pressure);
});
It seems you can't change, and by looking quickly at the API, it doesn't seem you have access to a state object.
In that case, if you want to use your member function, you need to introduce a global state:
// global variable
EncodeWrapper* encode = nullptr;
// in your function that sets the handle
encode = this; // v--- No capture makes it convertible to a function pointer
usbMIDI.setHandleAfterTouch([](uint8_t, channel, uint8_t pressure) {
encode->onAfterTouch(channel, pressure);
});
Another solution would be to make onAfterTouch function static. If it's static, it's pointer is not a member function pointer, but a normal function pointer.

Recursive function inside of a function c++

Say I have a wrapper function that goes around some smaller recursive function. However, the wrapper, before calling the recursive function creates an object which the recursive function uses. How can I do this in c++? Do I just need to make it its own class? EDIT - I know if I can make it into a class and how to take it from there - but my question is do I need a class or can I somehow getaway without making one?
I made a generic example to clarify my question:
void wrapper()
{
Object myObject;
bool recurFun(int x)
{
// do some stuff with myObject
if (some condition){return recurFun(x-1)}
else {return true}
}
}
Please ignore any basic syntax type errors, it is not a working example simply one to help get my question across to you guys. Thanks!
You can use lambdas to get closures:
void wrapper()
{
Object myObject;
std::function<bool(int)> recurFun;
recurFun = [&](int x) -> bool {
// do some stuff with myObject
if (some condition){return recurFun(x-1)}
else {return true}
}
}
The first thing that should come to your mind when a function needs to use something is to make it a parameter of that function. So have your recursive function accept the object as a parameter and thread it around in the recursive calls. The wrapper function will do the natural thing of setting up the object and passing it.

C++ Function Callbacks: Cannot convert from a member function to a function signature

I'm using a 3rd party library that allows me to register callbacks for certain events. The register function looks something like this. It uses the Callback signature.
typedef int (*Callback)(std::string);
void registerCallback(Callback pCallback) {
//it gets registered
}
My problem is that I want to register a member function as a callback something like this
struct MyStruct {
MyStruct();
int myCallback(std::string str);
};
MyStruct::MyStruct() {
registerCallback(&MyStruct::myCallback);
}
int MyStruct::myCallback(std::string str) {
return 0;
}
Of course, the compiler complains, saying
error C2664: 'registerCallback' : cannot convert parameter 1 from 'int (__thiscall MyStruct::* )(std::string)' to 'Callback'
I've been looking at boost libraries like function and bind, but none of those seem to be able to do the trick. I've been searching all over Google for the answer, but I don't even know what to call this, so it hasn't been much help.
Thanks in advance.
You're trying to pass a member function pointer as a normal function pointer which won't work. Member functions have to have the this pointer as one of the hidden parameters, which isn't the case for normal functions, so their types are incompatible.
You can:
Change the type of your argument to accept member functions and also accept an instance to be the invoking object
Quit trying to pass a member function and pass a normal function (perhaps by making the function static)
Have a normal function that takes an instance of your class, a member function pointer, and a std::string and use something like boost's bind to bind the first two arguments
Make the callback registration function accept a functor object, or an std::function (I think that's the name)
Numerous other ways which I won't detail here, but you get the drift.
Member functions are not convertible to the normal functions for its own good reasons. If your design allows, then make MyStruct::myCallback() a static member method and the code should work fine.
struct MyStruct {
...
static int myCallback(std::string str);
^^^^^^
};
Due to the inflexible hardcoding of an actual function type for the callback you can't use any of the normal adapting or binding tricks to help you here. The third party library really wants you to pass in a non-member function and there isn't much you can do. You may want to consider why you're trying to pass it the address of a member function, and if your design or use of the library could change.
One option, if you only need to set a single callback, is to have a static or namespace private function that refers to a singleton instance pointer, and uses that to dispatch upon callback.
If you need multiple items, then possibly a template would wrap the hackiness (untested code here, just the idea).
template <int which_callback>
struct CallbackHolderHack
{
static int callback_func(std::string str) { dispatchee_->myCallback(str); }
static MyStruct* dispatchee_;
};
template <int which_callback>
MyStruct* CallbackHolderHack::dispatchee_(0);
And use it:
CallbackHolderHack<0>::dispatchee_ = new MyStruct;
registerCallback(&CallbackHolderHack<0>::callback_func);
Depends on how you are using it.... eg a Singlton would be much simplier
struct MyStruct {
static MyStruct& Create() {
static MyStruct m; return m;
}
static int StaticCallBack(std::string str) {
return Create().Callback(str)
}
private:
int CallBack(std::string str);
MyStruct();
};
Or if you want to have many of these objects you have several choices. You would need a way to route it before the callback is called.
Since you are using C++, why not make the callback a functor object? Then you can use std::mem_fun.
Edit: Seems std::mem_fun has been deprecated in the latest C++11 standard. So std::function might be a better solution if you have a new compiler.
See this SO question for hints about using it.
class ICallBackInterface
{
public:
virtual void FireCallBack( std::string& str ) = 0;
};
std::set<ICallBackInterface*> CallBackMgr;
class MyStruct : public ICallBackInterface
{
public:
MyStruct()
{
CallBackMgr.insert( this );
}
~MyStruct()
{
CallBackMgr.erase( this );
}
virtual void FireCallBack( std::string& str )
{
std::cout << "MyStruct called\n";
}
};
void FireAllCallBack(std::string& str )
{
for ( std::set<ICallBackInterface*>::iterator iter = CallBackMgr.begin();
iter != CallBackMgr.end();
++iter)
{
(*iter)->FireCallBack( str );
}
}
This is another way to use polymorphism to achieve the same effect

Using boost thread and a non-static class function

So I have done some research, and have found you can create a boost::thread object and have it start with a non-static class function by using "this" and boost::bind etc. It really doesn't make much sense to me and all the examples I could find had the boost::thread object launched within the same class as the function it was starting with so this could be used. I however, am launching the thread in a different class so I'm afraid by using "this", I will be saying the "this" is from the class I am creating the thread from, rather than the one the function is in (I'm probably wrong, I need to learn more about this "this" guy). Here is an example of my source I am having the problem with.
ANNGUI.h
class ANNGUI
{
private:
boost::thread *GUIThread;
Main *GUIMain;
public:
// Creates the entire GUI and all sub-parts.
int CreateGUI();
}
ANNGUI.cpp
int ANNGUI::CreateGUI()
{
GUIMain = new Main();
GUIThread = new boost::thread(GUIMain->MainThreadFunc);
};
This isn't all the source, but I think my problem is in here somewhere, I know I have to deal with the "this" somehow, but I'm unsure how. I Could use a static function, but I didn't really want to make my variables static either.
Thanks.
Also, Is there any very good resource for using any boost libraries? Their web site documentation seems good, but over my head.
The this keyword is used with boost::bind when the function object you're creating is bound to a object member function. Member functions can't exist apart from instances, so when creating a functor object out of a member function with boost::bind, you need a pointer to an instance. That's exactly what the this keyword actually is. If you use the this keyword within a member function of a class, what you get is a pointer to the current instance of that class.
If you were to call bind from outside a class member function, you might say something like:
int main()
{
Foo f;
boost::thread* thr = new boost::thread(boost::bind(&Foo::some_function, &f));
}
Here, we're using Foo::some_function as our thread function. But we can't use this because we're calling bind from main. But the same thing could be achieved using this if we called bind from within a member function of Foo, like so:
void Foo::func1()
{
boost::thread* thr = new boost::thread(boost::bind(&Foo::some_function, this));
}
If a member function is static, or is simply a regular (non-member) function, then you don't need an instance pointer at all. You would just do:
boost::thread* thr = new boost::thread(some_regular_function);
As others mentioned, when you want to call an object method in a new thread, you have to supply the address of that object. But you don't need to call boost::bind, you can use the overloaded boost::thread constructor like this:
GUIThread = new boost::thread(&Main::MainThreadFunc, GUIMain);
If the method is in the same class you use this to get the address of the current instance, e.g.:
t = new boost::thread(&myclass::compute, this);
If the method has parameters, you can specify them after the second argument, e.g.:
t = new boost::thread(&myclass::compute, this, p1, p2);
boost::bind is your friend (it can sometimes have a rough way of showing it though)!
use GUIThread = new boost::thread(boost::bind(&Main::MainThreadFunc, GUIMain));
and then make your MainThreadFunc a regular member. That means that you can use the instance variables directly like you would normally do.
Something like this:
class GUIMain {
public:
GUIMain() : m_Member(42) {}
void MainThreadFunc() {
// use all members as you would normally do
std::cout << m_Member << std::endl;
}
private:
int m_Member;
};
In cases like this it is useful to think of non-static member functions as free functions that take the this as first parameter, for example in your case void MainThreadFunc(Main* this).
boost::thread accepts a nullary functor, so you have to pass it a nullary functor which contains a reference to the instance GUIMain and calls GUIMain->MainThreadFunc which, seen as I explained above, would be something like MainThreadFunc(GUIMain).
Boost (and now also C++ with TR1) provides helpers to create such functors, namely boost::bind (or alternatively boost::lambda::bind). The expression boost::bind(f, arg1, arg2, ...) means "return a nullary functor which calls f(arg1, arg2, ...)".
That said, you can use the following expression to create the thread:
GUIThread = new boost::thread(boost::bind(&Main::MainThreadFunc, GUIMain))
If your object is a functor, i.e. has an operator(), you can pass an instance of it to boost::thread. The operator() does not need to be static. For example:
#include <boost/thread.hpp>
struct th {
void operator()();
};
void th::operator()()
{
for (;;) {
// stuff
}
}
int main()
{
th t;
boost::thread my_thread( t ); // takes a copy of t !
my_thread.join(); // blocks
return 0;
}