传递一个可能更改为类实例的可调用函数

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

本文关键字:实例 函数 调用 一个      更新时间:2023-10-16

我有一组可调用对象,我想将其关联到特定类节点的实例。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"

我怎样才能做到这一点?可调用项的返回类型可能不同。

不再需要使用std::bind。Lambdas非常容易用于动态生成可调用对象,该对象还可以根据您的喜好存储任何类型的数据。

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