Search code examples
c++templatestemplate-argument-deduction

Why is the template argument deduction not working here?


I created two simple functions which get template parameters and an empty struct defining a type:

//S<T>::type results in T&
template <class T>
struct S
{
    typedef typename T& type;
};

//Example 1: get one parameter by reference and return it by value
template <class A>
A
temp(typename S<A>::type a1)
{
    return a1;
}

//Example 2: get two parameters by reference, perform the sum and return it
template <class A, class B>
B
temp2(typename S<A>::type a1, B a2)//typename struct S<B>::type a2)
{
    return a1 + a2;
}

The argument type is applied to the struct S to get the reference. I call them with some integer values but the compiler is unable to deduce the arguments:

int main()
{
    char c=6;
    int d=7;
    int res = temp(c);
    int res2 = temp2(d,7);
}

Error 1 error C2783: 'A temp(S::type)' : could not deduce template argument for 'A'

Error 2 error C2783: 'B temp2(S::type,B)' : could not deduce template argument for 'A'


Why is this happening? Is it that hard to see that the template arguments are char and int values?


Solution

  • Just as first note, typename name is used when you mention a dependent name. So you don't need it here.

    
    template <class T>
    struct S
    {
        typedef T& type;
    };
    

    Regarding the template instantiation, the problem is that typename S<A>::type characterizes a nondeduced context for A. When a template parameter is used only in a nondeduced context (the case for A in your functions) it's not taken into consideration for template argument deduction. The details are at section 14.8.2.4 of the C++ Standard (2003).

    To make your call work, you need to explicitly specify the type:

    
    temp<char>(c);