Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::function and shared_ptr

I have been using Loki's Functor for a while and I recently asked a question about it (still unanswered...) I have been told to use std::function, but I prefer Loki's implementation of Functor since it also work with all sorts of pointers as parameters (e.g. 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);
}

Is there a way to do so with std::function ?

like image 239
Athanase Avatar asked Dec 16 '13 10:12

Athanase


2 Answers

Use std::bind.

auto func = std::bind(&Toto::foo, ptr, std::placeholders::_1);

here, func will be deduced to type, that was returned from std::bind or if you don't like auto you can use (and you want to use std::function)

std::function<void(int)> func = std::bind(&Toto::foo, 
ptr, std::placeholders::_1);

Here std::function will be constructed from result of std::bind. ptr will be copied to some object returned from std::bind, however you can use std::ref/std::cref if you don't want copies.

like image 81
ForEveR Avatar answered Sep 27 '22 17:09

ForEveR


If you don't want to use std::bind, an option is to use a lambda function, resulting in even smaller code and I personally find it more intuitive:

auto func = [&ptr](int p){ ptr->foo(p); };

or without auto:

std::function<void(int)> func = [&ptr](int p){ ptr->foo(p); };

But this only works if the function to be called is fixed (i.e. &Toto::foo was not passed dynamically). If not, it's still possible with a lambda but you need a slightly different syntax and std::bind might be more attractive again.

like image 45
leemes Avatar answered Sep 27 '22 18:09

leemes