0

Why does callB(f) compile and callA(f) does not compile? Aren't they kind of the same? I have tried with gcc and MSVC... same results.

#include <functional>

template<typename T>
struct Function
{
    typedef std::function<void(T)> type;
};

template<typename T = int>
void callA(std::function<void(T)> f)
{
    f(T());
}

template<typename T = int>
void callB(typename Function<T>::type f)
{
    f(T());
}

int main()
{
    auto f = [](int) { };

    callA(f);    // compile error: "template argument deduction/substitution failed: main()::<lambda(int)>’ is not derived from ‘std::function<void(T)>"
    callB(f);    // compiles

    return 0;
}
Tom
  • 171
  • 2
  • 6
  • 2
    Does this answer your question well enough? https://stackoverflow.com/questions/25245453/what-is-a-nondeduced-context – chris Nov 08 '18 at 21:24
  • @chris Thank you for the link. So for callA T is in deducible context, but cannot be deduced -> compile error (although the compiler could try the default type int?, but I guess thats on purpose). And callB is non-deducible context, so it won't try to deduce and simply try with the default type int. Is that correct? – Tom Nov 08 '18 at 22:06
  • That sounds right, but now I'm unsure of why A fails. I'm not sure what the exact rules when you have both a defaulted template parameter that would cause the call to succeed and where deduction from the function argument fails. Perhaps it is as simple as the default template argument never coming into play. – chris Nov 08 '18 at 22:39

0 Answers0