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?
Template argument deduction is used when selecting user-defined conversion function template arguments. A is the type that is required as the result of the conversion. P is the return type of the conversion function template.
Type inference or deduction refers to the automatic detection of the data type of an expression in a programming language. It is a feature present in some strongly statically typed languages. In C++, the auto keyword(added in C++ 11) is used for automatic type deduction.
A template parameter is a special kind of parameter that can be used to pass a type as argument: just like regular function parameters can be used to pass values to a function, template parameters allow to pass also types to a function.
1) A template template parameter with an optional name. 2) A template template parameter with an optional name and a default. 3) A template template parameter pack with an optional name.
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);
It is looks like nondeduced context. According to C++ Standard 14.8.2.4/4:
The nondeduced contexts are:
- The nested-name-specifier of a type that was specified using a qualified-id.
- A type that is a template-id in which one or more of the template-arguments is an expression that references a template-parameter.
When a type name is specified in a way that includes a nondeduced context, all of the types that comprise that type name are also nondeduced. However, a compound type can include both deduced and nondeduced types. [Example: If a type is specified as
A<T>::B<T2>
, bothT
andT2
are nondeduced. Likewise, if a type is specified asA<I+J>::X<T>
,I
,J
, andT
are nondeduced. If a type is specified asvoid f(typename A<T>::B, A<T>)
, theT
inA<T>::B
is nondeduced but theT
inA<T>
is deduced. ]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With