Attach callback function without `std::function` [duplicate] - c++

I want to be able to call functions based on the data I read from file.
So for each item type, I want to call the desired reader method.
I wrote this code, but it does not compile where I want to add function pointers to the map. What is wrong?
#include <vector>
#include <map>
#include <iostream>
class reader
{
std::map< std::string, void(*)()> functionCallMap; // function pointer
void readA(){ std::cout << "reading A\n";};
void readB(){ std::cout << "reading B\n";};;
public:
reader()
{
*functionCallMap["A"] = &reader::readA;*
*functionCallMap["B"] = &reader::readB;*
}
void read()
{
auto (*f) = functionCallMap["A"];
(*f)();
}
};
I am filling the map at Constructor.

You can use std::function with a lambda or std::bind :
class reader
{
std::map<std::string, std::function<void()>> functionCallMap;
void readA() { std::cout << "reading A\n"; };
void readB() { std::cout << "reading B\n"; };
public:
reader()
{
functionCallMap["A"] = [this]() { readA(); };
functionCallMap["B"] = std::bind(&reader::readB, this);
}
void read()
{
functionCallMap["A"]();
functionCallMap["B"]();
}
};

You need to use pointers to member functions, like this:
class reader
{
using FuncPtr = void(reader::*)(); // function pointer
std::map< std::string, FuncPtr> functionCallMap;
void readA(){ std::cout << "reading A\n"; }
void readB(){ std::cout << "reading B\n"; }
public:
reader()
{
functionCallMap["A"] = &reader::readA;
functionCallMap["B"] = &reader::readB;
}
void read()
{
auto f = functionCallMap["A"];
(this->*f)();
}
};
int main()
{
reader r;
r.read();
}

There are two answers so far, this and this.
The obvious difference is that one uses std::function and other uses function pointers. This is not the important difference!!
The key point is that the member functions are non-static member functions. So, they are not of type void().
They are of type void(reader::*)(). Thus, they can be only called if an object of type is reader is given; one can understand this somewhat as a hidden parameter.
The first answer just fixes the problem by specifying the correct type. This can be done using function pointers (as presented) or using std::function (The latter is much more expensive!).
The second answer fixes the problem by binding the function pointer to the particular instance of the class. After binding, the type is then indeed void(). This cannot be done using raw function pointers (because they can only point to a function and not an object/function pair!).

I ended up with this solution. It does the job, but I have some doubts over its aesthetics. Anyway, to sum up, I ended up with this code:
#include <map>
#include <iostream>
#include <functional>
class reader
{
std::map< std::string, std::function<void(std::string tableName)>> functionCallMap; // function pointer
void readA(const std::string tableName){ std::cout << "reading:" << tableName<< "\n"; }
void readB(const std::string tableName){ std::cout << "reading:" << tableName <<"\n"; }
public:
reader()
{
functionCallMap["A"] = std::bind(&reader::readA, this, std::placeholders::_1);
functionCallMap["B"] = std::bind(&reader::readA, this, std::placeholders::_1);
}
void read()
{
const std::string table_name = "A";
functionCallMap[table_name](table_name);
}
};
int main()
{
reader r;
r.read();
}
I pass the table name to the reader, it is nicely done with the bind and placeholder.

Related

How to store methods as function pointers in a map container?

I want to be able to call functions based on the data I read from file.
So for each item type, I want to call the desired reader method.
I wrote this code, but it does not compile where I want to add function pointers to the map. What is wrong?
#include <vector>
#include <map>
#include <iostream>
class reader
{
std::map< std::string, void(*)()> functionCallMap; // function pointer
void readA(){ std::cout << "reading A\n";};
void readB(){ std::cout << "reading B\n";};;
public:
reader()
{
*functionCallMap["A"] = &reader::readA;*
*functionCallMap["B"] = &reader::readB;*
}
void read()
{
auto (*f) = functionCallMap["A"];
(*f)();
}
};
I am filling the map at Constructor.
You can use std::function with a lambda or std::bind :
class reader
{
std::map<std::string, std::function<void()>> functionCallMap;
void readA() { std::cout << "reading A\n"; };
void readB() { std::cout << "reading B\n"; };
public:
reader()
{
functionCallMap["A"] = [this]() { readA(); };
functionCallMap["B"] = std::bind(&reader::readB, this);
}
void read()
{
functionCallMap["A"]();
functionCallMap["B"]();
}
};
You need to use pointers to member functions, like this:
class reader
{
using FuncPtr = void(reader::*)(); // function pointer
std::map< std::string, FuncPtr> functionCallMap;
void readA(){ std::cout << "reading A\n"; }
void readB(){ std::cout << "reading B\n"; }
public:
reader()
{
functionCallMap["A"] = &reader::readA;
functionCallMap["B"] = &reader::readB;
}
void read()
{
auto f = functionCallMap["A"];
(this->*f)();
}
};
int main()
{
reader r;
r.read();
}
There are two answers so far, this and this.
The obvious difference is that one uses std::function and other uses function pointers. This is not the important difference!!
The key point is that the member functions are non-static member functions. So, they are not of type void().
They are of type void(reader::*)(). Thus, they can be only called if an object of type is reader is given; one can understand this somewhat as a hidden parameter.
The first answer just fixes the problem by specifying the correct type. This can be done using function pointers (as presented) or using std::function (The latter is much more expensive!).
The second answer fixes the problem by binding the function pointer to the particular instance of the class. After binding, the type is then indeed void(). This cannot be done using raw function pointers (because they can only point to a function and not an object/function pair!).
I ended up with this solution. It does the job, but I have some doubts over its aesthetics. Anyway, to sum up, I ended up with this code:
#include <map>
#include <iostream>
#include <functional>
class reader
{
std::map< std::string, std::function<void(std::string tableName)>> functionCallMap; // function pointer
void readA(const std::string tableName){ std::cout << "reading:" << tableName<< "\n"; }
void readB(const std::string tableName){ std::cout << "reading:" << tableName <<"\n"; }
public:
reader()
{
functionCallMap["A"] = std::bind(&reader::readA, this, std::placeholders::_1);
functionCallMap["B"] = std::bind(&reader::readA, this, std::placeholders::_1);
}
void read()
{
const std::string table_name = "A";
functionCallMap[table_name](table_name);
}
};
int main()
{
reader r;
r.read();
}
I pass the table name to the reader, it is nicely done with the bind and placeholder.

C++: How to store various member functions of different classes for later use

thanks in advance for your support.
I'm using C++11 and I want to store public member functions of some classes for later use as callback functions; e.g. I want to store some functions that matches this template: void(classname::*)(void). As far as I know, I have to store their objects too, It's fine. For example:
// PSEUDO CODE
class A {
public:
void myfunc() {}
}myobj;
class B {
public:
void myfunc2() {}
}myobj2;
/* storing */
mystorageclass storage;
storage.push(&myobj, &A::myfunc);
storage.push(&myobj2, &B::myfunc2);
/* call them back */
(storage[0].object->*(storage[0].callback))();
(storage[1].object->*(storage[1].callback))();
Is there any safe and generic way to do that? Actually I've found a way, but I'm not sure how much it's portable across processors or compilers.
//test.cpp - compiled with: g++ test.cpp -o test -std=c++11
#include <iostream>
#include <vector>
class A {
public:
void myfunc() { std::cout << "Test A::myfunc()" << std::endl; }
}myobj;
class B {
public:
void myfunc2() { std::cout << "Test B::myfunc2()" << std::endl; }
}myobj2;
struct Callback {
void* object;
void(* method)(void*);
};
std::vector<Callback> callbackList;
template<typename FunctionPtr>
void add(void* object, FunctionPtr fptr) {
Callback cb;
cb.object = object;
cb.method = (void(*)(void*))(*(void**)(&fptr));
callbackList.push_back(cb);
}
int main() {
//add to list for later use
add(&myobj, &A::myfunc);
add(&myobj2, &B::myfunc2);
//call them back
callbackList[0].method(callbackList[0].object);
callbackList[1].method(callbackList[1].object);
}
And another way to do; I feel this is much more safe:
//test2.cpp - compiled with: g++ test2.cpp -o test2 -std=c++11
#include <iostream>
#include <vector>
class A {
public:
void myfunc() { std::cout << "Test A::myfunc()" << std::endl; }
}myobj;
class B {
public:
void myfunc2() { std::cout << "Test B::myfunc2()" << std::endl; }
}myobj2;
struct Callback {
struct A;
A* object;
void(A::* method)();
void call() {
(object->*method)();
}
};
std::vector<Callback> callbackList;
template<typename FunctionPtr>
void add(void* object, FunctionPtr fptr) {
Callback cb;
cb.object = (Callback::A*)object;
cb.method = (void(Callback::A::*)())(fptr);
callbackList.push_back(cb);
}
int main() {
//add to list for later use
add(&myobj, &A::myfunc);
add(&myobj2, &B::myfunc2);
//call them back
callbackList[0].call();
callbackList[1].call();
}
Does these usages are safe? Or what do you suggest instead of these.
Thanks.
Replace Callback with std::function<void()>.
Replace add with
template<class T, class R, class U>
void add(T* object, R(U::*ptr)()) {
Callback cb = [object, ptr]{ object->ptr(); };
callbackList.push_back(cb);
// or just
// callbackList.push_back([object, ptr]{ object->ptr(); });
}
note that this supports passing in pointers-to-parent member functions, and callbacks that do not return void and discarding the result.
std::function stores a generic "call this later". You pass a type compatible with the return value, and args compatible with what you want to call later, in the template signature argument of std::function<signature>. In this case, <void()>.
Problem with the second version
In the line
cb.method = (void(*)(void*))(*(void**)(&fptr));
you are casting a function pointer to void**. I am not sure that is supported by the standard. My guess is it is not. I know casting a function pointer to void* is not supported by the standard. See Print an address of function in C++, g++/clang++ vs vc++ , who is rght? for details.
And then, you proceed to use:
callbackList[1].method(callbackList[1].object);
This relies on conventions used by a compiler to pass this as the first hidden argument when calling a member function of a class. There is no guarantee that the method is used by all compilers. The standard does not explicitly state that.
Problem with the third/last version
You are using:
cb.object = (Callback::A*)object;
cb.method = (void(Callback::A::*)())(fptr);
regardless of whether the object type is A or B. This is cause for undefined behavior. The standard does not support casting of an object pointer to any old pointer type.
A Cleaner Version
Use a base class for Callback.
struct Callback {
virtual ~Callback() = 0;
virtual void call() = 0;
};
Then, use a class template for the real Callbacks.
template <typename T>
struct RealCallback : public Callback
{
RealCallback(T* obj, void (T::*m)(void)) : object(obj), method(m) {}
virtual void call()
{
(object->*method)();
}
T* object;
void (T::*method)();
};
With this, you won't be able to store a list of Callback objects but you can store a list of shared_ptr<Callback>s.
std::vector<std::shared_ptr<Callback>> callbackList;
Here's a complete program that does not rely on any ugly casts and works perfectly.
//test.cpp - compiled with: g++ test.cpp -o test -std=c++11
#include <iostream>
#include <vector>
#include <memory>
class A {
public:
void myfunc() { std::cout << "Test A::myfunc() on " << this << std::endl; }
}myobj;
class B {
public:
void myfunc2() { std::cout << "Test B::myfunc2() on " << this << std::endl; }
}myobj2;
struct Callback {
virtual void call() = 0;
};
template <typename T>
struct RealCallback : public Callback
{
RealCallback(T* obj, void (T::*m)(void)) : object(obj), method(m) {}
virtual void call()
{
(object->*method)();
}
T* object;
void (T::*method)();
};
std::vector<std::shared_ptr<Callback>> callbackList;
template<typename T>
void add(T* object, void (T::*fptr)()) {
RealCallback<T>* cb = new RealCallback<T>(object, fptr);
callbackList.push_back(std::shared_ptr<Callback>(cb));
}
int main() {
//add to list for later use
add(&myobj, &A::myfunc);
add(&myobj2, &B::myfunc2);
std::cout << "myobj: " << &myobj << std::endl;
std::cout << "myobj2: " << &myobj2 << std::endl;
//call them back
callbackList[0]->call();
callbackList[1]->call();
}
Update, in response to comment by Yakk
I think Yakk's suggestion makes sense. You can remove the classes Callback and RealCallback with
using Callback = std::function<void()>;
std::vector<Callback> callbackList;
Then, add can be simplified to:
template<class T>
void add(T* object, void(T::*ptr)()) {
callbackList.push_back([object, ptr]{ (object->*ptr)();});
}
With those changes, main needs to be slightly updated to:
int main() {
//add to list for later use
add(&myobj, &A::myfunc);
add(&myobj2, &B::myfunc2);
std::cout << "myobj: " << &myobj << std::endl;
std::cout << "myobj2: " << &myobj2 << std::endl;
// Updated. Can't use callbackList[0]->call();
//call them back
callbackList[0]();
callbackList[1]();
}
Try with std::function or std::bindboth of them need to keep the reference to the instance:
#include <string>
#include <iostream>
#include <functional>
using namespace std;
class MyClass
{
int _value;
public:
MyClass(int value)
{
_value = value;
}
void food()
{
cout << "Foo is doing something whit value: " << _value << endl;
}
void bar()
{
cout << "Bar is doing something whit value: " << _value << endl;
}
};
int main()
{
MyClass* c1 = new MyClass(1);
MyClass* c2 = new MyClass(2);
cout << "Using 'std::function':" << endl;
std::function<void(MyClass&)> food = &MyClass::food;
std::function<void(MyClass&)> bar = &MyClass::bar;
food(*c1);
bar(*c1);
food(*c2);
bar(*c2);
cout << "Using 'std::bind':" << endl;
auto foodBind = std::bind(&MyClass::food, std::placeholders::_1);
auto barBind = std::bind(&MyClass::bar, std::placeholders::_1);
foodBind(*c1);
barBind(*c1);
foodBind(*c2);
barBind(*c2);
system("PAUSE");
};
the Output is:

Check validity of std::function before calling?

I'm trying to program a simple but flexible event system (mostly just as an exercise, I know there are existing libraries that have really good event handlers), and I've run into a little stumbling block.
How can you check if an std::function that's a delegate (probably through a lambda, possibly though std::bind) is a valid function/if the object for the member function still exists before calling it? I've tried simply using std::function's bool operator, but haven't had any success.
Ideally I'd like to A. do the checking somewhere other than inside the delegate function, and B. still have the code be valid when the std::function that's being checked isn't a delegate.
Any ideas?
Edit: Here's the source for the test that I ran
#include <iostream>
#include <string>
#include <functional>
class Obj {
public:
std::string foo;
Obj(std::string foo) : foo(foo) {}
std::function<void()> getDelegate() {
auto callback = [this]() {this->delegatedFn();};
return callback;
}
void delegatedFn() {
std::cout << foo << std::endl;
}
};
int main() {
Obj* obj = new Obj("bar");
std::function<void()> callback = obj->getDelegate();
callback();
delete obj;
//perform some type of check here whether function is valid, without needing to know whether the function is a delegate or not
if(callback) {
std::cout << "Callback is valid" << std::endl; //callback is still considered valid after obj is deleted
callback(); //no exception thrown, prints a random series of characters
}
else {
std::cout << "Callback is invalid" << std::endl;
}
return 0;
}
You can use smart pointers (std::shared_ptr/std::weak_ptr) instead of naked ones:
#include <iostream>
#include <string>
#include <functional>
#include <memory>
class Obj {
public:
std::string foo;
Obj(std::string foo) : foo(foo) {}
void delegatedFn() {
std::cout << foo << std::endl;
}
};
int main() {
auto obj = std::make_shared<Obj>("bar");
std::weak_ptr<Obj> ptr = obj;
std::function<void()> callback = [ptr](){
auto sh = ptr.lock();
if(sh) { std::cout << "valid" << std::endl; sh->delegatedFn(); }
else { std::cout << "invalid" << std::endl; }
};
callback();
obj = nullptr;
callback();
return 0;
}
In this case you are not directly checking the validity of a std::function (that is valid when you assign it something, even if that something captures a dangling pointer).
Instead, you check that the referred object is still alive from within the function itself.
The broadcaster/listener pattern I use looks like this:
template<class...Args>
struct broadcaster {
std::vector< std::weak_ptr< std::function<void(Args...)> > > callbacks;
void operator()(Args...args) const {
std::remove_erase_if( begin(callbacks), end(callbacks), [](auto&& ptr){return !ptr;} );
auto tmp = callbacks;
for (auto pf : tmp) {
if (pf && *pf) (*pf)(args...);
}
}
std::shared_ptr<void> listen( std::shared_ptr<std::function<void(Args...)>> f ) {
callbacks.push_back(f);
return f;
}
std::shared_ptr<void> listen( std::function<void(Args...)> f ) {
auto ptr = std::make_shared<std::function<void(Args...)>>(std::move(f));
return listen(ptr);
}
};
Listeners to a message .listen their callback with broadcaster. They get back a shared_ptr<void> token.
So long as that token exists, the broadcaster will send messages at the function object passed in.
Obj would either store a std::vector<std::shared_ptr<void>> tokens or a single std::shared_ptr<void>. When it was destroyed, its listeners would automatically deregister.
Alternatively, Obj could inherit from shared_from_this. Then it implements
std::function<void()> delegate;
std::shared_ptr<std::function<void()>> getDelegatedFn() {
if (!delegate) delegate = [this]{ this->delegateFn(); }
return {
&delegate,
shared_from_this()
};
}
which shares the lifetime of the Obj instance itself (uses the aliasing constructor of shared_ptr). Pass this to listen and done.

C++11 styled callbacks?

I have a void function inside of a class. In old C++ i'd make a function static taking the class name as a parameter and had my own class which took a static void function + a void* for me to easily call it.
However that feels old school. It also isn't templated which feels like i could be doing more. What is a more modern way of creating callbacks to myclassVar.voidReturnVoidParamFunc
Use std::function and lambdas (or std::bind()) to store callables:
#include <functional>
#include <iostream>
class Test
{
public:
void blah() { std::cout << "BLAH!" << std::endl; }
};
class Bim
{
public:
void operator()(){ std::cout << "BIM!" << std::endl; }
};
void boum() { std::cout << "BOUM!" << std::endl; }
int main()
{
// store the member function of an object:
Test test;
std::function< void() > callback = std::bind( &Test::blah, test );
callback();
// store a callable object (by copy)
callback = Bim{};
callback();
// store the address of a static function
callback = &boum;
callback();
// store a copy of a lambda (that is a callable object)
callback = [&]{ test.blah(); }; // often clearer -and not more expensive- than std::bind()
callback();
}
Result:
BLAH!
BIM!
BOUM!
BLAH!
Compiles and run: http://ideone.com/T6wVp
std::function can be used as any copyiable object, so feel free to store it somewhere as a callback, like in object's member. It also means that you can freely put it in standard containers, like std::vector< std::function< void () > > .
Also note that equivalent boost::function and boost::bind have been available for years.
For an example of passing in parameters to a C++ 11 callback using Lambda's and a vector, see http://ideone.com/tcBCeO or below:
class Test
{
public:
Test (int testType) : m_testType(testType) {};
void blah() { std::cout << "BLAH! " << m_testType << std::endl; }
void blahWithParmeter(std::string p) { std::cout << "BLAH1! Parameter=" << p << std::endl; }
void blahWithParmeter2(std::string p) { std::cout << "BLAH2! Parameter=" << p << std::endl; }
private:
int m_testType;
};
class Bim
{
public:
void operator()(){ std::cout << "BIM!" << std::endl; }
};
void boum() { std::cout << "BOUM!" << std::endl; }
int main()
{
// store the member function of an object:
Test test(7);
//std::function< void() > callback = std::bind( &Test::blah, test );
std::function< void() > callback = std::bind( &Test::blah, test );
callback();
// store a callable object (by copy)
callback = Bim{};
callback();
// store the address of a static function
callback = &boum;
callback();
// store a copy of a lambda (that is a callable object)
callback = [&]{ test.blah(); }; // might be clearer than calling std::bind()
callback();
// example of callback with parameter using a vector
typedef std::function<void(std::string&)> TstringCallback;
std::vector <TstringCallback> callbackListStringParms;
callbackListStringParms.push_back( [&] (const std::string& tag) { test.blahWithParmeter(tag); });
callbackListStringParms.push_back( [&] (const std::string& tag) { test.blahWithParmeter2(tag); });
std::string parm1 = "parm1";
std::string parm2 = "parm2";
int i = 0;
for (auto cb : callbackListStringParms )
{
++i;
if (i == 1)
cb(parm1);
else
cb(parm2);
}
}

How to get Windows thread pool to call class member function?

I want the Windows thread pool (QueueUserWorkItem()) to call my class' member functions.
Unfortunately this cannot be done directly by passing a member function pointer as an argument to QueueUserWorkItem().
What makes it difficult is that more than one member function must be callable and they have different signatures (all return void though).
One probably need to add a few layers of abstraction to get this to work, but I'm not sure how to approach this. Any ideas?
This might help.
You can use tr1::function () and tr1::bind to "coalesce" various calls:
#include <iostream>
#include <tr1/functional>
using namespace std;
using namespace tr1;
class A
{
public:
void function(int i) { cout << "Called A::function with i=" << i << endl; }
};
void different_function(double c) {
cout << "Called different_function with c=" << c << endl;
}
int main(int argc, char* argv[])
{
function<void()> f = bind(different_function, 3.14165);
f();
A a;
f = bind(&A::function, a, 10);
f();
return 0;
}
The address of the function object can be passed as a single callable object (needing only one address).
Example:
In your class add:
char m_FuncToCall;
static DWORD __stdcall myclass::ThreadStartRoutine(LPVOID myclassref)
{
myclass* _val = (myclass*)myclassref;
switch(m_FuncToCall)
{
case 0:
_val->StartMyOperation();
break;
}
return 0;
}
Make a member for adding to queue then
void myclass::AddToQueue(char funcId)
{
m_FuncToCall=funcId;
QueueUserWorkItem(ThreadStartRoutine,this,WT_EXECUTEDEFAULT);
}
or create
typedef void (*MY_FUNC)(void);
typedef struct _ARGUMENT_TO_PASS
{
myclass* classref;
MY_FUNC func;
}ARGUMENT_TO_PASS;
and then
void myclass::AddToQueue(MY_FUNC func)
{
ARGUMENT_TO_PASS _arg;
_arg.func = func;
_arg.classref = this;
QueueUserWorkItem(ThreadStartRoutine,&_arg,WT_EXECUTEDEFAULT);
}
If you need further explanation feel free to ask :)
EDIT: You'll need to change the ThreadStartRoutine for the second example
and you can also change the struct to hold the passing argument