Стандарт C++ 98 (1119566), страница 70
Текст из файла (страница 70)
[Example:namespace N {template<class T1, class T2> class A { };}using N::A;// refers to the primary templatenamespace N {template<class T> class A<T, T*> { };}A<int,int*> a;// primary template// partial specialization// uses the partial specialization, which is found through// the using declaration which refers to the primary template—end example]8A non-type argument is non-specialized if it is the name of a non-type parameter. All other non-type arguments are specialized.9Within the argument list of a class template partial specialization, the following restrictions apply:— A partially specialized non-type argument expression shall not involve a template parameter of the partial specialization except when the argument expression is a simple identifier.
[Example:template <int I, int J> struct A {};template <int I> struct A<I+5, I*2> {}; // errortemplate <int I, int J> struct B {};template <int I> struct B<I, I> {};// OK—end example]— The type of a template parameter corresponding to a specialized non-type argument shall not be dependent on a parameter of the specialization. [Example:251ISO/IEC 14882:1998(E)© ISO/IEC14.5.4 Class template partial specializations14 Templatestemplate <class T, T t> struct C {};template <class T> struct C<T, 1>;// errortemplate< int X, int (*array_ptr)[X] > class A {};int array[5];template< int X > class A<X,&array> { };// error—end example]— The argument list of the specialization shall not be identical to the implicit argument list of the primarytemplate.10The template parameter list of a specialization shall not contain default template argument values.129)14.5.4.1 Matching of class template partial specializations1[temp.class.spec.match]When a class template is used in a context that requires an instantiation of the class, it is necessary to determine whether the instantiation is to be generated using the primary template or one of the partial specializations.
This is done by matching the template arguments of the class template specialization with the template argument lists of the partial specializations.— If exactly one matching specialization is found, the instantiation is generated from that specialization.— If more than one matching specialization is found, the partial order rules (14.5.4.2) are used to determine whether one of the specializations is more specialized than the others.
If none of the specializations is more specialized than all of the other matching specializations, then the use of the class templateis ambiguous and the program is ill-formed.— If no matches are found, the instantiation is generated from the primary template.2A partial specialization matches a given actual template argument list if the template arguments of the partial specialization can be deduced from the actual template argument list (14.8.2).
[Example:A<int, int, 1>A<int, int*, 1>A<int, char*, 5>A<int, char*, 1>A<int*, int*, 2>a1;a2;a3;a4;a5;// uses #1// uses #2, T is int, I is 1// uses #4, T is char// uses #5, T1 is int, T2 is char, I is 1// ambiguous: matches #3 and #5—end example]3A non-type template argument can also be deduced from the value of an actual template argument of anon-type parameter of the primary template. [Example: the declaration of a2 above. ]4In a type name that refers to a class template specialization, (e.g., A<int, int, 1>) the argument listmust match the template parameter list of the primary template.
The template arguments of a specializationare deduced from the arguments of the primary template.14.5.4.2 Partial ordering of class template specializations1[temp.class.order]For two class template partial specializations, the first is at least as specialized as the second if, given thefollowing rewrite to two function templates, the first function template is at least as specialized as the second according to the ordering rules for function templates (14.5.5.2):— the first function template has the same template parameters as the first partial specialization and has asingle function parameter whose type is a class template specialization with the template arguments ofthe first partial specialization, and— the second function template has the same template parameters as the second partial specialization andhas a single function parameter whose type is a class template specialization with the template__________________129) There is no way in which they could be used.252© ISO/IECISO/IEC 14882:1998(E)14 Templates14.5.4.2 Partial ordering of class template specializationsarguments of the second partial specialization.2[Example:template<int I, int J, class T> class X { };template<int I, int J>class X<I, J, int> { };template<int I>class X<I, I, int> { };template<int I, int J> void f(X<I, J, int>);template<int I>void f(X<I, I, int>);// #1// #2// #A// #BThe partial specialization #2 is more specialized than the partial specialization #1 because the functiontemplate #B is more specialized than the function template #A according to the ordering rules for functiontemplates.
]14.5.4.3 Members of class template specializations1[temp.class.spec.mfunc]The template parameter list of a member of a class template partial specialization shall match the templateparameter list of the class template partial specialization. The template argument list of a member of a classtemplate partial specialization shall match the template argument list of the class template partial specialization. A class template specialization is a distinct template. The members of the class template partialspecialization are unrelated to the members of the primary template. Class template partial specializationmembers that are used in a way that requires a definition shall be defined; the definitions of members of theprimary template are never used as definitions for members of a class template partial specialization.
Anexplicit specialization of a member of a class template partial specialization is declared in the same way asan explicit specialization of the primary template. [Example:// primary templatetemplate<class T, int I> struct A {void f();};template<class T, int I> void A<T,I>::f() { }// class template partial specializationtemplate<class T> struct A<T,2> {void f();void g();void h();};// member of class template partial specializationtemplate<class T> void A<T,2>::g() { }// explicit specializationtemplate<> void A<char,2>::h() { }int main(){A<char,0> a0;A<char,2> a2;a0.f();a2.g();a2.h();a2.f();// OK, uses definition of primary template’s member// OK, uses definition of// partial specialization’s member// OK, uses definition of// explicit specialization’s member// ill-formed, no definition of f for A<T,2>// the primary template is not used here}—end example]253ISO/IEC 14882:1998(E)© ISO/IEC14.5.4.3 Members of class template specializations214 TemplatesIf a member template of a class template is partially specialized, the member template partial specializations are member templates of the enclosing class template; if the enclosing class template is instantiated(14.7.1, 14.7.2), a declaration for every member template partial specialization is also instantiated as part ofcreating the members of the class template specialization.
If the primary member template is explicitly specialized for a given (implicit) specialization of the enclosing class template, the partial specializations of themember template are ignored for this specialization of the enclosing class template. If a partial specialization of the member template is explicitly specialized for a given (implicit) specialization of the enclosingclass template, the primary member template and its other partial specializations are still considered for thisspecialization of the enclosing class template.
[Example:template<class T> struct A {template<class T2> struct B {};template<class T2> struct B<T2*> {};};// #1// #2template<> template<class T2> struct A<short>::B {};A<char>::B<int*> abcip;A<short>::B<int*> absip;A<char>::B<int> abci;// #3// uses #2// uses #3// uses #1—end example]14.5.5 Function templates1[temp.fct]A function template defines an unbounded set of related functions. [Example: a family of sort functionsmight be declared like this:template<class T> class Array { };template<class T> void sort(Array<T>&);—end example]2A function template can be overloaded with other function templates and with normal (non-template) functions.
A normal function is not related to a function template (i.e., it is never considered to be a specialization), even if it has the same name and type as a potentially generated function template specialization.130)14.5.5.1 Function template overloading1[temp.over.link]It is possible to overload function templates so that two different function template specializations have thesame type.
[Example:// file1.ctemplate<class T>void f(T*);void g(int* p) {f(p); // call// f<int>(int*)}// file2.ctemplate<class T>void f(T);void h(int* p) {f(p); // call// f<int*>(int*)}—end example]2Such specializations are distinct functions and do not violate the one definition rule (3.2).3The signature of a function template specialization consists of the signature of the function template and ofthe actual template arguments (whether explicitly specified or deduced).__________________130) That is, declarations of non-template functions do not merely guide overload resolution of template functions with the same name.If such a non-template function is used in a program, it must be defined; it will not be implicitly instantiated using the function template definition.254© ISO/IECISO/IEC 14882:1998(E)14 Templates414.5.5.1 Function template overloadingThe signature of a function template consists of its function signature, its return type and its templateparameter list.
The names of the template parameters are significant only for establishing the relationshipbetween the template parameters and the rest of the signature. [Note: two distinct function templates mayhave identical function return types and function parameter lists, even if overload resolution alone cannotdistinguish them.template<class T> void f();template<int I> void f();// OK: overloads the first template// distinguishable with an explicit template argument list—end note]5When an expression that references a template parameter is used in the function parameter list or the returntype in the declaration of a function template, the expression that references the template parameter is partof the signature of the function template.