Search code examples
c++templatesstdstd-function

In what situation do I have to use a std::function?


It's hard for me to imagine a genuine use case for std::function that couldn't be covered by a template. Every time I consider using std::function, I find a way to avoid it:

// implementation using std::function
void forEach(std::array<int, 100> &data, const std::function<void(int&)> &f)
{
    for (size_t i = 0; i < 100; ++i) {
        f(data[i]);
    }
}

// implementation using any functor which takes an int&
template <typename Callable>
void forEach(std::array<int, 100> &data, const Callable &f)
     requires std::is_invocable_v<Callable, int&>
{
    for (size_t i = 0; i < 100; ++i) {
        f(data[i]);
    }
}

Admittedly, the implementation using std::function is a bit shorter, but due to type erasure it requires a virtual call each iteration and the compiler can't optimize it well. (Live example)

So what would be a genuine use case for std::function where a template couldn't be used instead? Is there any need for std::function at all?


Solution

  • std::function type-erases a callable type and makes it possible to treat them homogenously.

    For example, you can have a vector of callbacks:

    std::vector<std::function<int(std::string)>> callbacks;