我已经使用 Loki's Functor 一段时间了,最近我问了一个关于它的问题(仍然没有答案......) 我被告知要使用 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 做到这一点?
使用
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
。
如果你不想使用
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
可能会再次更具吸引力。
使用
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
实际上是不必要的,但我将其留在这里作为更高级用法的说明。