Стандарт C++ 98 (1119566), страница 71
Текст из файла (страница 71)
This is necessary to permit a declaration of a function template inone translation unit to be linked with another declaration of the function template in another translation unitand, conversely, to ensure that function templates that are intended to be distinct are not linked with oneanother. [Example:template <int I, int J> A<I+J> f(A<I>, A<J>);template <int K, int L> A<K+L> f(A<K>, A<L>);template <int I, int J> A<I-J> f(A<I>, A<J>);// #1// same as #1// different from #1—end example] [Note: Most expressions that use template parameters use non-type template parameters,but it is possible for an expression to reference a type parameter.
For example, a template type parametercan be used in the sizeof operator. ]6Two expressions involving template parameters are considered equivalent if two function definitions containing the expressions would satisfy the one definition rule (3.2), except that the tokens used to name thetemplate parameters may differ as long as a token used to name a template parameter in one expression isreplaced by another token that names the same template parameter in the other expression. [Example:template <int I, int J> void f(A<I+J>);template <int K, int L> void f(A<K+L>);// #1// same as #1—end example] Two expressions involving template parameters that are not equivalent are functionallyequivalent if, for any given set of template arguments, the evaluation of the expression results in the samevalue.7Two function templates are equivalent if they are declared in the same scope, have the same name, haveidentical template parameter lists, and have return types and parameter lists that are equivalent using therules described above to compare expressions involving non-type template parameters.
Two function templates are functionally equivalent if they are equivalent except that one or more non-type expressions thatinvolve template parameters in the return types and parameter lists are functionally equivalent using therules described above to compare expressions involving non-type template parameters. If a program contains declarations of function templates that are functionally equivalent but not equivalent, the program isill-formed; no diagnostic is required.8[Note: This rule guarantees that equivalent declarations will be linked with one another, while not requiringimplementations to use heroic efforts to guarantee that functionally equivalent declarations will be treatedas distinct.
For example, the last two declarations are functionally equivalent and would cause a program tobe ill-formed:255ISO/IEC 14882:1998(E)14.5.5.1 Function template overloading© ISO/IEC14 Templates// Guaranteed to be the sametemplate <int I> void f(A<I>, A<I+10>);template <int I> void f(A<I>, A<I+10>);// Guaranteed to be differenttemplate <int I> void f(A<I>, A<I+10>);template <int I> void f(A<I>, A<I+11>);// Ill-formed, no diagnostic requiredtemplate <int I> void f(A<I>, A<I+10>);template <int I> void f(A<I>, A<I+1+2+3+4>);—end note]14.5.5.2 Partial ordering of function templates1[temp.func.order]If a function template is overloaded, the use of a function template specialization might be ambiguousbecause template argument deduction (14.8.2) may associate the function template specialization with morethan one function template declaration.
Partial ordering of overloaded function template declarations isused in the following contexts to select the function template to which a function template specializationrefers:— during overload resolution for a call to a function template specialization (13.3.3);— when the address of a function template specialization is taken;— when a placement operator delete that is a template function specialization is selected to match a placement operator new (3.7.3.2, 5.3.4);— when a friend function declaration (14.5.3), an explicit instantiation (14.7.2) or an explicit specialization(14.7.3) refers to a function template specialization.2Given two overloaded function templates, whether one is more specialized than another can be determinedby transforming each template in turn and using argument deduction (14.8.2) to compare it to the other.3The transformation used is:— For each type template parameter, synthesize a unique type and substitute that for each occurrence ofthat parameter in the function parameter list, or for a template conversion function, in the return type.— For each non-type template parameter, synthesize a unique value of the appropriate type and substitutethat for each occurrence of that parameter in the function parameter list, or for a template conversionfunction, in the return type.— For each template template parameter, synthesize a unique class template and substitute that for eachoccurrence of that parameter in the function parameter list, or for a template conversion function, in thereturn type.4Using the transformed function parameter list, perform argument deduction against the other function template.
The transformed template is at least as specialized as the other if, and only if, the deduction succeedsand the deduced parameter types are an exact match (so the deduction does not rely on implicit conversions).5A template is more specialized than another if, and only if, it is at least as specialized as the other templateand that template is not at least as specialized as the first.
[Example:256© ISO/IECISO/IEC 14882:1998(E)14 Templates14.5.5.2 Partial ordering of function templatestemplate<class T> struct A { A(); };template<class T> void f(T);template<class T> void f(T*);template<class T> void f(const T*);template<class T> void g(T);template<class T> void g(T&);template<class T> void h(const T&);template<class T> void h(A<T>&);void m() {const int *p;f(p);float x;g(x);A<int> z;h(z);const A<int> z2;h(z2);}// f(const T*) is more specialized than f(T) or f(T*)// Ambiguous: g(T) or g(T&)// overload resolution selects h(A<T>&)// h(const T&) is called because h(A<T>&) is not callable—end example]6The presence of unused ellipsis and default arguments has no effect on the partial ordering of function templates. [Example:template<classtemplate<classtemplate<classtemplate<classT>T>T>T>int main() {int* ip;f(ip);g(ip);}voidvoidvoidvoidf(T);f(T*, int=1);g(T);g(T*, ...);// #1// #2// #3// #4// calls #2// calls #4—end example]14.6 Name resolution1[temp.res]Three kinds of names can be used within a template definition:— The name of the template itself, and names declared within the template itself.— Names dependent on a template-parameter (14.6.2).— Names from scopes which are visible within the template definition.2A name used in a template declaration or definition and that is dependent on a template-parameter isassumed not to name a type unless the applicable name lookup finds a type name or the name is qualifiedby the keyword typename.
[Example:257ISO/IEC 14882:1998(E)© ISO/IEC14.6 Name resolution14 Templates// no B declared hereclass X;template<class T> class Y {class Z;// forward declaration of member classvoid f() {X* a1;// declare pointer to XT* a2;// declare pointer to TY* a3;// declare pointer to Y<T>Z* a4;// declare pointer to Ztypedef typename T::A TA;TA* a5;// declare pointer to T’s Atypename T::A* a6;// declare pointer to T’s AT::A* a7;// T::A is not a type name:// multiply T::A by a7; ill-formed,// no visible declaration of a7B* a8;// B is not a type name:// multiply B by a8; ill-formed,// no visible declarations of B and a8}};—end example]3A qualified-name that refers to a type and that depends on a template-parameter (14.6.2) shall be prefixedby the keyword typename to indicate that the qualified-name denotes a type, forming an elaborated-typespecifier (7.1.5.3).elaborated-type-specifier:.
. .typename ::opt nested-name-specifier identifiertypename ::opt nested-name-specifier identifier < template-argument-list >. . .4If a specialization of a template is instantiated for a set of template-arguments such that the qualified-nameprefixed by typename does not denote a type, the specialization is ill-formed. The usual qualified namelookup (3.4.3) is used to find the qualified-name even in the presence of typename. [Example:struct A {struct X { };int X;};template<class T> void f(T t) {typename T::X x;// ill-formed: finds the data member X// not the member type X}—end example]5The keyword typename shall only be used in template declarations and definitions, including in the returntype of a function template or member function template, in the return type for the definition of a memberfunction of a class template or of a class nested within a class template, and in the type-specifier for the definition of a static member of a class template or of a class nested within a class template.
The keywordtypename shall only be applied to qualified names, but those names need not be dependent. The keywordtypename is not permitted in a base-specifier or in a mem-initializer; in these contexts a qualified-namethat depends on a template-parameter (14.6.2) is implicitly assumed to be a type name.6Within the definition of a class template or within the definition of a member of a class template, the keyword typename is not required when referring to the unqualified name of a previously declared memberof the class template that declares a type. The keyword typename shall always be specified when the258© ISO/IECISO/IEC 14882:1998(E)14 Templates14.6 Name resolutionmember is referred to using a qualified name, even if the qualifier is simply the class template name.[Example:template<class T> struct A {typedef int B;A::B b;void f(A<T>::B);typename A::B g();};// ill-formed: typename required before A::B// ill-formed: typename required before A<T>::B// OKThe keyword typename is required whether the qualified name is A or A<T> because A or A<T> are synonyms within a class template with the parameter list <T>.
]7Knowing which names are type names allows the syntax of every template definition to be checked. Nodiagnostic shall be issued for a template definition for which a valid specialization can be generated. If novalid specialization can be generated for a template definition, and that template is not instantiated, the template definition is ill-formed, no diagnostic required. [Note: if a template is instantiated, errors will be diagnosed according to the other rules in this Standard.