将可能更改为 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();
}
我有一组可调用对象,我想将其关联到特定 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();
}