我一直在使用Loki的Functor一段时间,我最近问过question有关它(仍然没有答案......) 我被告知使用std :: function,但我更喜欢Loki的Functor实现,因为它也可以作为参数使用各种指针(例如std :: shared_ptr)。
struct Toto
{
void foo( int param )
{
std::cout << "foo: " << param << std::endl;
}
};
int
main( int argc, const char** argv )
{
std::shared_ptr<Toto> ptr = std::make_shared<Toto>();
Loki::Functor<void, LOKI_TYPELIST_1(int)> func( ptr, &Toto::foo );
func(1);
}
有没有办法用std :: function做到这一点?
答案 0 :(得分:6)
使用std::bind
。
auto func = std::bind(&Toto::foo, ptr, std::placeholders::_1);
此处,func
将被推断为类型,是从std::bind
返回的,或者如果您不喜欢auto
可以使用(并且您想使用std::function
})
std::function<void(int)> func = std::bind(&Toto::foo,
ptr, std::placeholders::_1);
此处std::function
将根据std::bind
的结果构建。
ptr
将被复制到std::bind
返回的某个对象,但如果您不想要副本,则可以使用std::ref
/ std::cref
。
答案 1 :(得分:2)
如果您不想使用std::bind
,可以选择使用lambda函数,从而产生更小的代码,我个人觉得它更直观:
auto func = [&ptr](int p){ ptr->foo(p); };
或没有auto
:
std::function<void(int)> func = [&ptr](int p){ ptr->foo(p); };
但这仅在要调用的函数是固定的(即&Toto::foo
未动态传递)时才有效。如果没有,它仍然可以使用lambda,但你需要稍微不同的语法,而std::bind
可能会再次具有吸引力。
答案 2 :(得分:1)
使用std::bind
。
struct Toto
{
void foo( int param )
{
std::cout << "foo: " << param << std::endl;
}
};
int main() {
std::shared_ptr<Toto> ptr = std::make_shared<Toto>();
std::function< void(int) > func( std::bind( &Toto::foo,
std::bind( [ptr] () { return ptr.get(); } ),
std::placeholders::_1
) );
func( 1 );
}
编辑:带有lambda表达式的内部bind
实际上是不必要的,但我将这里留下来作为更高级用法的说明。