Search code examples
c++templatesstd-functiontemplate-argument-deduction

Using std::function with templates


So in it's most distilled form I have something like this going on,

template <class T>
bool f(const T &a, const T &b, std::function<bool(const T&, const T&)> func)
{
    return func(a,b);
}

template <class T>
bool g(const T &a, const T &b)
{
    return true;
}  

But any attempt to call f(), with anything, f('a', 'b', g), f(1, 2, g), always results in "no matching function for call to 'f'", regardless of whether I pass the variables as const references or just plain values or whatever. I'm assuming it's failing to deduce some template, but I have no idea where or why.

I will admit, I have a very tenuous grasp on how to use function objects in general, is doing something like this even possible?


Solution

  • The parameter func is declared as std::function, and you're trying to pass a function pointer, which requires implicit conversion. Template argument deduction doesn't consider implicit conversion and then deduction fails.

    Type deduction does not consider implicit conversions (other than type adjustments listed above): that's the job for overload resolution, which happens later.

    You can construct an std::function explicitly,

    f('a', 'b', static_cast<std::function<bool(const char&, const char&)>>(g<char>));
    

    Or specify the template argument explicitly (to bypass template argument deduction and make implicit conversion taking effect later),

    f<char>('a', 'b', g<char>);    
    

    Or just don't use std::function.

    template <class T, class F>
    bool f(const T &a, const T &b, F func)
    {
        return func(a,b);
    }
    
    f('a', 'b', g<char>);