【问题标题】:C++ - Pass member function to member object with std::functionC++ - 使用 std::function 将成员函数传递给成员对象
【发布时间】:2016-02-18 00:36:13
【问题描述】:

我正在尝试将成员函数对象传递给成员对象,但在 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() 成员函数中调用它(将由父对象的@ 调用987654326@成员函数)

我研究过类似的问题。许多人建议使用 std::mem_fn 但当我不清楚如何在此设置中使用它时(函数必须传递给不同的对象)。

【问题讨论】:

    标签: c++ visual-studio-2013


    【解决方案1】:

    所需的函数签名是void (*)(void),但printSimpleFoo 的签名是void (Foo::*)(void)

    您可以使用std::bind 来捕获对象实例。对象实例是必需的,因为您不能使用关联的对象实例调用成员函数。 std::bind 本质上存储了对象实例,以便函数具有适当的签名。

    bar.setFunct(std::bind(&amp;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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-26
      • 2014-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多