将可能更改为 class 的实例的可调用对象传递

Passing a callable that may change to an instance of a class

我有一组可调用对象,我想将其关联到特定 class Node 的实例。 Node 的每个实例只需要持有一个可调用对象,并且可以从成员函数中调用它。假设 A、B 和 C 是可调用对象,它们可能具有不同的函数签名:

Node n1,n2,n3;
n1.associate(A);
n2.associate(B, 42);
n3.associate(C, "foo");

//...

n1.mem_fn(); //will call A at some point inside some_other_fn()
n2.mem_fn(); //will call B, passing 42 as argument

//...

n1.associate(C, "bar");
n1.mem_fn(); //now C will replace A, and be called from n1::mem_fn() with arg "bar"

我怎样才能做到这一点?可调用对象的 return 类型可能不同。

无需再使用 std::bind。 Lambda 非常易于使用,可以动态生成可调用对象,该对象还可以存储您喜欢的任何类型的数据。

class Node 
{
    private:
        std::function<void(void)> fn;

    public:
        template <typename F, typename ... PARMS>
        void associate( F f, PARMS ... parms )
        {
            // Generate a lambda which captures all given parms
            // and if executed, the lambda calls f with all
            // the captured parms. This on the fly generated 
            // lambda will be stored in std::function 
            fn = [f, parms...](){ f( parms...); };
        }

        void mem_fn()
        {
            // Here we simply call our lambda which will call 
            // the stored function with the also stored parms
            fn();
        }
};

void A() { std::cout << "A" << std::endl; }
void B( int i ) { std::cout << "B " << i << std::endl; }
void C( const std::string& s ) { std::cout << "C " << s << std::endl; }

// I use exact copy of your code as copy here:
int main()
{
    Node n1,n2,n3;
    n1.associate(A);
    n2.associate(B, 42);
    n3.associate(C, "foo");

    n1.mem_fn(); //will call A at some point inside some_other_fn()
    n2.mem_fn(); //will call B, passing 42 as argument

    //...

    n1.associate(C, "bar"); //now C will replace A, and be called from n1::mem_fn() with arg "bar"
    n1.mem_fn();
}