Search code examples
c++templateslambdastd-function

Why code below doesn't compile and what can we do to make it compile in the end?


My code:

#include <functional>
#include <iostream>

template <typename T>
void call_with(std::function<void(T)> f, T val)
{
    f(val);
}

int main()
{
    auto print = [](int x) { std::cout << x; };
    call_with(print, 42);
}

The error I get:

Error (active) E0304 no instance of function template "call_with" matches the argument list

Why do we even need std::function if it can't automatically convert from lambdas? Or there is some special behaviour due to templates?


Solution

  • The type for your template cannot be automatically deduced in this line:

    call_with(print, 42);
    

    Because a lambda is not a std::function (although it can be converted to one).

    You can solve it by specifying the template argument explicitly:

    call_with<int>(print, 42);
    

    Live demo 1

    Alternatively as suggested in the comment you can avoid using std::function in your template and use another generic parameter that can be replaced with any callable:

    template<typename F, typename T> 
    void call_with(F f, T const& value) 
    { 
        f(value); 
    }
    

    And then use it as you attempted:

    call_with(print, 42);
    

    Live demo 2