7

我使用 Loki 的 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 做到这一点?

4

3 回答 3

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

于 2013-12-16T11:08:20.093 回答
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可能再次更具吸引力。

于 2013-12-16T11:26:02.950 回答
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 );
}

现场演示。

编辑:bind带有 lambda 表达式的内部实际上是不必要的,但我将把它留在这里作为更高级用法的说明。

于 2013-12-16T11:11:05.783 回答