我正在尝试将成员函数对象传递给成员对象但是我在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,> *'
以下是代码:
#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;
}
所以我希望Bar
能够使用特定签名获取任意函数,即void(void)
来自其父对象,并在run()
成员函数中调用它(这将是由父母start()
成员函数调用
我调查了类似的问题。许多人建议使用std :: mem_fn,但是当我不清楚如何在这个设置中使用它时(必须将函数传递给不同的对象)。
答案 0 :(得分:1)
所需的功能签名为void (*)(void)
,但printSimpleFoo
的签名为void (Foo::*)(void)
。
您可以使用std::bind
捕获对象实例。对象实例是必需的,因为您无法使用关联的对象实例调用成员函数。 std::bind
实质上存储了对象实例,以便该函数具有适当的签名。
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