Стандарт C++ 98 (1119566), страница 75
Текст из файла (страница 75)
*/ };template<class T> class Array { /* ... */ };template<class T> void sort(Array<T>& v) { /* ... */ }template<> void sort<char*>(Array<char*>&) ;Given these declarations, stream<char> will be used as the definition of streams of chars; otherstreams will be handled by class template specializations instantiated from the class template. Similarly,sort<char*> will be used as the sort function for arguments of type Array<char*>; other Arraytypes will be sorted by functions generated from the template.
]2An explicit specialization shall be declared in the namespace of which the template is a member, or, formember templates, in the namespace of which the enclosing class or enclosing class template is a member.An explicit specialization of a member function, member class or static data member of a class templateshall be declared in the namespace of which the class template is a member.
Such a declaration may alsobe a definition. If the declaration is not a definition, the specialization may be defined later in the namespace in which the explicit specialization was declared, or in a namespace that encloses the one in whichthe explicit specialization was declared.3A declaration of a function template or class template being explicitly specialized shall be in scope at thepoint of declaration of an explicit specialization. [Note: a declaration, but not a definition of the template isrequired. ] The definition of a class or class template shall be in scope at the point of declaration of anexplicit specialization for a member template of the class or class template. [Example:template<> class X<int> { /* ...
*/ };// error: X not a templatetemplate<class T> class X;template<> class X<char*> { /* ... */ };// OK: X is a template—end example]4A member function, a member class or a static data member of a class template may be explicitly specialized for a class specialization that is implicitly instantiated; in this case, the definition of the class templateshall be in scope at the point of declaration of the explicit specialization for the member of the class template. If such an explicit specialization for the member of a class template names an implicitly-declaredspecial member function (clause 12), the program is ill-formed.5A member of an explicitly specialized class is not implicitly instantiated from the member declaration ofthe class template; instead, the member of the class template specialization shall itself be explicitly defined.In this case, the definition of the class template explicit specialization shall be in scope at the point of declaration of the explicit specialization of the member.
The definition of an explicitly specialized class is unrelated to the definition of a generated specialization. That is, its members need not have the same names,types, etc. as the members of the a generated specialization. Definitions of members of an explicitly specialized class are defined in the same manner as members of normal classes, and not using the explicit specialization syntax.
[Example:273ISO/IEC 14882:1998(E)© ISO/IEC14.7.3 Explicit specialization14 Templatestemplate<class T> struct A {void f(T) { /* ... */ }};template<> struct A<int> {void f(int);};void h(){A<int> a;a.f(16);}// A<int>::f must be defined somewhere// explicit specialization syntax not used for a member of// explicitly specialized class template specializationvoid A<int>::f() { /* ... */ }—end example]6If a template, a member template or the member of a class template is explicitly specialized then that specialization shall be declared before the first use of that specialization that would cause an implicit instantiation to take place, in every translation unit in which such a use occurs; no diagnostic is required. If the program does not provide a definition for an explicit specialization and either the specialization is used in away that would cause an implicit instantiation to take place or the member is a virtual member function, theprogram is ill-formed, no diagnostic required.
An implicit instantiation is never generated for an explicitspecialization that is declared but not defined. [Example:template<class T> class Array { /* ... */ };template<class T> void sort(Array<T>& v) { /* ... */ }void f(Array<String>& v){sort(v);// use primary template// sort(Array<T>&), T is String}template<> void sort<String>(Array<String>& v); // error: specialization// after use of primary templatetemplate<> void sort<>(Array<char*>& v);// OK: sort<char*> not yet used—end example]7The placement of explicit specialization declarations for function templates, class templates, member functions of class templates, static data members of class templates, member classes of class templates, memberclass templates of class templates, member function templates of class templates, member functions ofmember templates of class templates, member functions of member templates of non-template classes,member function templates of member classes of class templates, etc., and the placement of partial specialization declarations of class templates, member class templates of non-template classes, member class templates of class templates, etc., can affect whether a program is well-formed according to the relative positioning of the explicit specialization declarations and their points of instantiation in the translation unit asspecified above and below.
When writing a specialization, be careful about its location; or to make it compile will be such a trial as to kindle its self-immolation.8When a specialization for which an explicit specialization exists is used within the instantiation of anexported template, and the unspecialized template name is non-dependent in the exported template, a declaration of the explicit specialization shall be declared before the definition of the exported template, in thetranslation unit containing that definition. [Example:274© ISO/IECISO/IEC 14882:1998(E)14 Templates14.7.3 Explicit specialization// file #1#include <vector>// Primary class template vectorexport template<class T> void f(t) {vector<T> vec;// should match the specialization/* ...
*/}// file #2#include <vector>class B { };// Explicit specialization of vector for vector<B>template<class T> class vector<B> { /* ... */ }template<class T> void f(T);void g(B b) {f(b);// ill-formed:// f<B> should refer to vector<B>, but the// specialization was not declared with the// definition of f in file #1}—end example]9A template explicit specialization is in the scope of the namespace in which the template was defined.[Example:namespace N {template<class T> class X { /* ...
*/ };template<class T> class Y { /* ... */ };template<> class X<int> { /* ... */ };template<> class Y<double>;// OK: specialization// in same namespace// forward declare intent to// specialize for double}template<> class N::Y<double> { /* ... */ };// OK: specialization// in same namespace—end example]10A template-id that names a class template explicit specialization that has been declared but not defined canbe used exactly like the names of other incompletely-defined classes (3.9). [Example:template<class T> class X;template<> class X<int>;// X is a class templateX<int>* p;X<int> x;// OK: pointer to declared class X<int>// error: object of incomplete class X<int>—end example]11A trailing template-argument can be left unspecified in the template-id naming an explicit function template specialization provided it can be deduced from the function argument type.
[Example:template<class T> class Array { /* ... */ };template<class T> void sort(Array<T>& v);// explicit specialization for sort(Array<int>&)// with deduces template-argument of type inttemplate<> void sort(Array<int>&);—end example]275ISO/IEC 14882:1998(E)© ISO/IEC14.7.3 Explicit specialization1214 TemplatesIt is possible for a specialization with a given function signature to be instantiated from more than one function template. In such cases, explicit specification of the template arguments must be used to uniquelyidentify the function template specialization being specialized. [Example:templatetemplatetemplatetemplatetemplate<class T> void f(T);<class T> void f(T*);<>void f(int*);<>void f<int>(int*);<>void f(int);// Ambiguous// OK// OK—end example]13A function with the same name as a template and a type that exactly matches that of a template specialization is not an explicit specialization (14.5.5).14An explicit specialization of a function template is inline only if it is explicitly declared to be, and independently of whether its function template is.
[Example:template<class T> void f(T) { /* ... */ }template<class T> inline T g(T) { /* ... */ }template<> inline void f<>(int) { /* ... */ }template<> int g<>(int) { /* ... */ }// OK: inline// OK: not inline—end example]15An explicit specialization of a static data member of a template is a definition if the declaration includes aninitializer; otherwise, it is a declaration. [Note: there is no syntax for the definition of a static data memberof a template that requires default initialization.template<> X Q<int>::x;This is a declaration regardless of whether X can be default initialized (8.5). ]16A member or a member template of a class template may be explicitly specialized for a given implicitinstantiation of the class template, even if the member or member template is defined in the class templatedefinition.
An explicit specialization of a member or member template is specified using the template specialization syntax. [Example:template<class T> struct A {void f(T);template<class X> void g(T,X);void h(T) { }};// specializationtemplate<> void A<int>::f(int);// out of class member template definitiontemplate<class T> template<class X> void A<T>::g(T,X) { }// member template partial specializationtemplate<> template<class X> void A<int>::g(int,X);// member template specializationtemplate<> template<>void A<int>::g(int,char);// X deduced as chartemplate<> template<>void A<int>::g<char>(int,char); // X specified as char// member specialization even if defined in class definitiontemplate<> void A<int>::h(int) { }—end example]276© ISO/IEC14 Templates17ISO/IEC 14882:1998(E)14.7.3 Explicit specializationA member or a member template may be nested within many enclosing class templates.