C ++ - 使用std :: function将成员函数传递给成员对象

时间:2016-02-17 16:27:17

标签: c++ visual-studio-2013

我正在尝试将成员函数对象传递给成员对象但是我在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,但是当我不清楚如何在这个设置中使用它时(必须将函数传递给不同的对象)。

1 个答案:

答案 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

Live Example