0

Dear stackoverflow users.

I tried to find the advantages of std::function, and why I should use it instead of functors or pointers to function. Sadly I did not find a satisfying answer.

That is why I will much appreciate if you would tell me what are advantages of std::function, and when should I use it. Hope that my question will help others as well.

Jens
  • 8,423
  • 9
  • 58
  • 78
FieryCod
  • 1,674
  • 1
  • 19
  • 27
  • 4
    Good explanation is [The importance of std::function](https://probablydance.com/2012/12/16/the-importance-of-stdfunction/). Related articles: [Why do we use std::function...](http://stackoverflow.com/questions/11352936/why-do-we-use-stdfunction-in-c-rather-than-the-original-c-function-pointer) and [Should I use std::function...](http://stackoverflow.com/questions/25848690/should-i-use-stdfunction-or-a-function-pointer-in-c). – Jens Jun 07 '16 at 06:03

2 Answers2

7

std::function implements a technique called type-erasure because of which you can store any callable entity in std::function, be it functors, member functions, or free functions — you can even store member-data as well which seems counter intuitive!

Here is one example, which cannot be done without std::function (or type-erasure):

std::vector<std::function<void()>>  funs;
for(int i = 0; i < 10; ++i)
  funs.push_back([i] { std::cout << i < std::endl; });

for(auto const & f: funs)
   f();

Here is another example which stores member-data:

struct person
{ 
    std::string name;
};

int main()
{
    std::vector<person> people {
      {"Bjarne"},
      {"Alex"}
    };

    std::function<std::string(person const&)> name (&person::name);

    for(auto const & p : people)
       std::cout << name(p) << std::endl;
}

Output (demo):

Bjarne
Alex

Hope that helps.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
1

The point of std::function is to provide type erasure over a generic callable object with some given prototype. You use it when you want your function/your class/whatever to receive some generic callable object with a certain signature (be it a function pointer, a functor or a lambda) without having to make everything template over the type of such callable.

Also, there are situations where even making everything template wouldn't help; think about having a vector of heterogeneous "stuff" that can be called, for example a signal-like object. Without this kind of type erasure it is essentially impossible.

Matteo Italia
  • 123,740
  • 17
  • 206
  • 299