Question

#include <functional>

using namespace std;

template<class CharType>
void f1(CharType* str, function<bool(CharType)> fn_filter)
{}

template<class CharType>
void f2(CharType* str, function<bool(char)> fn_filter)
{}

void f3(char* str, char c)
{
    auto fn_filter = [=](char e) -> bool 
    {
        return e == c; 
    };

    f1(str, fn_filter); // error C2784
    f2(str, fn_filter); // OK
}

int main()
{
    f3("ok", 'k');
}

// error C2784: 'void f1(CharType *,std::function<bool(CharType)>)' 
// : could not deduce template argument for 'std::function<bool(CharType)>' 
// from 'f2::<lambda_36be5ecc63077ff97cf3d16d1d5001cb>'

My compiler is VC++ 2013.

Why does f1 not work as expected?

Was it helpful?

Solution 2

The problem for the compiler is to decide which of your parameters to use for the type deduction. If you help the compile by breaking the possible deduction from the second parameter and force it to use the first, it works as expected:

template<typename T> struct identity { using type = T; };

template<class CharType>
void f1(CharType* str, typename identity<function<bool(CharType)>>::type fn_filter)
{}

Live example

OTHER TIPS

The lambda doesn't have type std::function<bool(char)>, it is just some callable object with implementation defined type.

It can be converted to std::function<bool(char)>, but that doesn't help the compiler to deduce the type for the template case. There could for example be lot's of possibilities for CharType for which the lambda can be converted to std::function<bool(CharType)>.

The compiler tries to match the type of the lambda against the parameter of the template function. The lambda has for example a type like lambda_t_1234 and the template parameter is std::function<bool(CharType)>. The types are unrelated and it's not clear what CharType is supposed to be here.

This also isn't special to lambdas or std::function<>. The same happens in all such cases:

template<typename Char>
void f(const std::basic_string<Char> &str) {
}

If you try to call this template function with a char* parameter it won't work, because the connection to the template parameter isn't clear.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top