Reputation: 804
I am trying to pass a member function object to a member object but I am getting the following error in VS 2013:
error C2664: 'void std::_Func_class<_Ret,>::_Set(std::_Func_base<_Ret,> *)' : cannot convert argument 1 from '_Myimpl *' to 'std::_Func_base<_Ret,> *'
Here's the code:
#include <iostream>
#include <functional>
class Bar {
public:
Bar(){};
Bar(std::function<void(void)> funct_) : funct(funct_){}
void setFunct(std::function<void(void)> funct_){
funct = funct_;
}
void run(){
for (int k = 0; k < 10; k++)
funct();
};
std::function<void(void)> funct;
};
class Foo{
public:
Foo(){
bar.setFunct(&Foo::printSimpleFoo);
}
void printSimpleFoo(){
std::cout << "Hello World" << std::endl;
}
void start(){
bar.run();
}
private:
Bar bar;
};
int _tmain(int argc, _TCHAR* argv[])
{
Foo foo;
foo.start();
system("pause");
return 0;
}
So I want Bar
to be able to take an arbitrary function with the specific signature, i.e. void(void)
from its parent object and the call it in its run()
member function (which will be called by the parent's start()
member function)
I have looked into similar questions. Many suggest using std::mem_fn but when it is not clear to me how to use it in this setting (where the function has to be passed to different object).
Upvotes: 0
Views: 154
Reputation: 9602
The desired function signature is void (*)(void)
however the signature of printSimpleFoo
is void (Foo::*)(void)
.
You can use std::bind
to capture the object instance. The object instance is necessary because you cannot call a member function with the associated object instance. The std::bind
essentially stores the object instance so that the function has the appropriate signature.
bar.setFunct(std::bind(&Foo::printSimpleFoo, this));
#include <iostream>
#include <functional>
class Bar
{
public:
Bar() {}
Bar(std::function<void(void)> funct_) : funct(funct_) {}
void setFunct(std::function<void(void)> funct_)
{
funct = funct_;
}
void run()
{
for (int k = 0; k < 10; ++k)
{
funct();
}
};
std::function<void(void)> funct;
};
class Foo
{
public:
Foo()
{
bar.setFunct(std::bind(&Foo::printSimpleFoo, this));
}
void printSimpleFoo()
{
std::cout << "Hello World\n";
}
void start()
{
bar.run();
}
private:
Bar bar;
};
int main()
{
Foo foo;
foo.start();
return 0;
}
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Upvotes: 1