std :: function和shared_ptr

时间:2013-12-16 10:58:27

标签: c++ std-function loki

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

3 个答案:

答案 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 );
}

Live demo.

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