Стандарт C++ 98 (1119566), страница 78
Текст из файла (страница 78)
That is, they may be used to determine the value of a template argument, and thevalue so determined must be consistent with the values determined elsewhere. In certain contexts, however, the value does not participate in type deduction, but instead uses the values of template arguments thatwere either deduced elsewhere or explicitly specified. If a template parameter is used only in nondeducedcontexts and is not explicitly specified, template argument deduction fails.4The 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 comprisethat 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>, both T and T2 are nondeduced. Likewise, if a type is specified as A<I+J>::X<T>, I, J, and T are nondeduced. If a type is specified as voidf(A<T>::B, A<T>), the T in A<T>::B is nondeduced but the T in A<T> is deduced. ]5[Example: Here is an example in which different parameter/argument pairs produce inconsistent templateargument deductions:template<class T> void f(T x, T y) { /* ...
*/ }struct A { /* ... */ };struct B : A { /* ... */ };int g(A a, B b){f(a,b);// error: T could be A or Bf(b,a);// error: T could be A or Bf(a,a);// OK: T is Af(b,b);// OK: T is B}6Here is an example where two template arguments are deduced from a single function parameter/argumentpair. This can lead to conflicts that cause type deduction to fail:284© ISO/IECISO/IEC 14882:1998(E)14 Templates14.8.2.4 Deducing template arguments from a typetemplate <class T, class U> void f(T (*)( T, U, U ));int g1( int, float, float);char g2( int, float, float);int g3( int, char, float);void r(){f(g1);f(g2);f(g3);}7// OK: T is int and U is float// error: T could be char or int// error: U could be char or floatHere is an example where a qualification conversion applies between the argument type on the function calland the deduced template argument type:template<class T> void f(const T*) {}int *p;void s(){f(p);// f(const int *)}8Here is an example where the template argument is used to instantiate a derived class type of the corresponding function parameter type:template <class T>template <class T>struct D2 : publictemplate <class T>void t(){D<int> d;D2d2;f(d);f(d2);}struct B { };struct D : public B<T> {};B<int> {};void f(B<T>&){}// calls f(B<int>&)// calls f(B<int>&)—end example]9A template type argument T, a template template argument TT or a template non-type argument i can bededuced if P and A have one of the following forms:285ISO/IEC 14882:1998(E)14.8.2.4 Deducing template arguments from a type© ISO/IEC14 TemplatesTcv-list TT*T&T[integer-constant]template-name<T> (where template-name refers to a class template)type(*)(T)T(*)()T(*)(T)T type::*type T::*T T::*T (type::*)()type (T::*)()type (type::*)(T)type (T::*)(T)T (type::*)(T)T (T::*)()T (T::*)(T)type[i]template-name<i> (where template-name refers to a class template)TT<T>TT<i>TT<>where (T) represents argument lists where at least one argument type contains a T, and () representsargument lists where no parameter contains a T.
Similarly, <T> represents template argument lists whereat least one argument contains a T, <i> represents template argument lists where at least one argumentcontains an i and <> represents template argument lists where no argument contains a T or an i.10These forms can be used in the same way as T is for further composition of types. [Example:X<int> (*)(char[6])is of the formtemplate-name<T> (*)(type[i])which is a variant oftype (*)(T)where type is X<int> and T is char[6].
]11Template arguments cannot be deduced from function arguments involving constructs other than the onesspecified above.12A template type argument cannot be deduced from the type of a non-type template-argument. [Example:template<class T, T i> void f(double a[10][i]);int v[10][20];f(v);// error: argument for template-parameter T cannot be deduced—end example]13[Note: except for reference and pointer types, a major array bound is not part of a function parameter typeand cannot be deduced from an argument:template<int i> void f1(int a[10][i]);template<int i> void f2(int a[i][20]);template<int i> void f3(int (&a)[i][20]);286© ISO/IEC14 Templatesvoid g(){int v[10][20];f1(v);f1<20>(v);f2(v);f2<10>(v);f3(v);}14ISO/IEC 14882:1998(E)14.8.2.4 Deducing template arguments from a type// OK: i deduced to be 20// OK// error: cannot deduce template-argument i// OK// OK: i deduced to be 10If, in the declaration of a function template with a non-type template-parameter, the non-type templateparameter is used in an expression in the function parameter-list, the corresponding template-argumentmust always be explicitly specified or deduced elsewhere because type deduction would otherwise alwaysfail for such a template-argument.template<int i> class A { /* ...
*/ };template<short s> void g(A<s+1>);void k() {A<1> a;g(a);// error: deduction fails for expression s+1g<0>(a);// OK}—end note] [Note: template parameters do not participate in template argument deduction if they are usedonly in nondeduced contexts. For example,template<int i, typename T>T deduce(typename A<T>::X x,Tt,typename B<i>::Y y);A<int> a;B<77> b;// T is not deduced here// but T is deduced here// i is not deduced hereintx = deduce<77>(a.xm, 62, y.ym);// T is deduced to be int, a.xm must be convertible to// A<int>::X// i is explicitly specified to be 77, y.ym must be convertible// to B<77>::Y—end note]15If, in the declaration of a function template with a non-type template-parameter, the non-type templateparameter is used in an expression in the function parameter-list and, if the corresponding templateargument is deduced, the template-argument type shall match the type of the template-parameter exactly,except that a template-argument deduced from an array bound may be of any integral type.132) [Example:template<int i> class A { /* ...
*/ };template<short s> void f(A<s>);void k1() {A<1> a;f(a);// error: deduction fails for conversion from int to shortf<1>(a);// OK}__________________132) Although the template-argument corresponding to a template-parameter of type bool may be deduced from an array bound, theresulting value will always be true because the array bound will be non-zero.287ISO/IEC 14882:1998(E)© ISO/IEC14.8.2.4 Deducing template arguments from a type14 Templatestemplate<const short cs> class B { };template<short s> void h(B<s>);void k2() {B<1> b;g(b);// OK: cv-qualifiers are ignored on template parameter types}—end example]16A template-argument can be deduced from a pointer to function or pointer to member function argument ifthe set of overloaded functions does not contain function templates and at most one of a set of overloadedfunctions provides a unique match.
[Example:template<class T> void f(void(*)(T,int));template<class T> void foo(T,int);void g(int,int);void g(char,int);void h(int,int,int);void h(char,int);int m(){f(&g);f(&h);f(&foo);}// error: ambiguous// OK: void h(char,int) is a unique match// error: type deduction fails because foo is a template—end example]17A template type-parameter cannot be deduced from the type of a function default argument. [Example:template <class T> void f(T = 5, T = 7);void g(){f(1);// OK: call f<int>(1,7)f();// error: cannot deduce Tf<int>();// OK: call f<int>(5,7)}—end example]18The template-argument corresponding to a template template-parameter is deduced from the type of thetemplate-argument of a class template specialization used in the argument list of a function call.
[Example:template <template X<class T> > struct A { };template <template X<class T> > void f(A<X>) { }template<class T> struct B { };A<B> ab;f(ab);// calls f(A<B>)—end example] [Note: a default template-argument cannot be specified in a function template declarationor definition; therefore default template-arguments cannot be used to influence template argument deduction.
]14.8.3 Overload resolution1[temp.over]A function template can be overloaded either by (non-template) functions of its name or by (other) functiontemplates of the same name. When a call to that name is written (explicitly, or implicitly using the operatornotation), template argument deduction (14.8.2) and checking of any explicit template arguments (14.3) areperformed for each function template to find the template argument values (if any) that can be used withthat function template to instantiate a function template specialization that can be invoked with the callarguments. For each function template, if the argument deduction and checking succeeds, the templatearguments (deduced and/or explicit) are used to instantiate a single function template specialization which288© ISO/IECISO/IEC 14882:1998(E)14 Templates14.8.3 Overload resolutionis added to the candidate functions set to be used in overload resolution. If, for a given function template,argument deduction fails, no such function is added to the set of candidate functions for that template.