简体   繁体   English

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

[英]C++ - Pass member function to member object with std::function

I am trying to pass a member function object to a member object but I am getting the following error in VS 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,> *'

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, ie 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) 所以我希望Bar能够采用具有特定签名的任意函数,即从其父对象中获取void(void)并在其run()成员函数中调用它(它将由父级的start()成员函数调用) )

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). 许多人建议使用std :: mem_fn,但是当我不清楚如何在此设置中使用它时(必须将函数传递给其他对象)。

The desired function signature is void (*)(void) however the signature of printSimpleFoo is void (Foo::*)(void) . 所需的函数签名为void (*)(void)但是printSimpleFoo的签名为void (Foo::*)(void)

You can use std::bind to capture the object instance. 您可以使用std::bind捕获对象实例。 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. std::bind本质上存储对象实例,以便函数具有适当的签名。

bar.setFunct(std::bind(&Foo::printSimpleFoo, this));

Example 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(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;
}

Example Code Output 示例代码输出

Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World

Live Example 现场例子

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM