- tmp/tmpg64u7i5q/{from.md → to.md} +101 -59
tmp/tmpg64u7i5q/{from.md → to.md}
RENAMED
|
@@ -17,17 +17,19 @@ can be declared by a declaration introduced by `template<>`; that is:
|
|
| 17 |
``` bnf
|
| 18 |
explicit-specialization:
|
| 19 |
'template < >' declaration
|
| 20 |
```
|
| 21 |
|
|
|
|
|
|
|
| 22 |
``` cpp
|
| 23 |
template<class T> class stream;
|
| 24 |
|
| 25 |
-
template<> class stream<char> {
|
| 26 |
|
| 27 |
-
template<class T> class Array {
|
| 28 |
-
template<class T> void sort(Array<T>& v) {
|
| 29 |
|
| 30 |
template<> void sort<char*>(Array<char*>&);
|
| 31 |
```
|
| 32 |
|
| 33 |
Given these declarations, `stream<char>` will be used as the definition
|
|
@@ -35,34 +37,39 @@ of streams of `char`s; other streams will be handled by class template
|
|
| 35 |
specializations instantiated from the class template. Similarly,
|
| 36 |
`sort<char*>` will be used as the sort function for arguments of type
|
| 37 |
`Array<char*>`; other `Array` types will be sorted by functions
|
| 38 |
generated from the template.
|
| 39 |
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
[[
|
| 45 |
-
a declaration may also be a definition. If the declaration is not a
|
| 46 |
-
definition, the specialization may be defined later (
|
| 47 |
-
[[namespace.memdef]]).
|
| 48 |
|
| 49 |
A declaration of a function template, class template, or variable
|
| 50 |
template being explicitly specialized shall precede the declaration of
|
| 51 |
-
the explicit specialization.
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 55 |
|
| 56 |
``` cpp
|
| 57 |
-
template<> class X<int> {
|
| 58 |
|
| 59 |
template<class T> class X;
|
| 60 |
|
| 61 |
-
template<> class X<char*> {
|
| 62 |
```
|
| 63 |
|
|
|
|
|
|
|
| 64 |
A member function, a member function template, a member class, a member
|
| 65 |
enumeration, a member class template, a static data member, or a static
|
| 66 |
data member template of a class template may be explicitly specialized
|
| 67 |
for a class specialization that is implicitly instantiated; in this
|
| 68 |
case, the definition of the class template shall precede the explicit
|
|
@@ -85,10 +92,12 @@ manner as members of normal classes, and not using the `template<>`
|
|
| 85 |
syntax. The same is true when defining a member of an explicitly
|
| 86 |
specialized member class. However, `template<>` is used in defining a
|
| 87 |
member of an explicitly specialized member class template that is
|
| 88 |
specialized as a class template.
|
| 89 |
|
|
|
|
|
|
|
| 90 |
``` cpp
|
| 91 |
template<class T> struct A {
|
| 92 |
struct B { };
|
| 93 |
template<class U> struct C { };
|
| 94 |
};
|
|
@@ -100,40 +109,40 @@ template<> struct A<int> {
|
|
| 100 |
void h() {
|
| 101 |
A<int> a;
|
| 102 |
a.f(16); // A<int>::f must be defined somewhere
|
| 103 |
}
|
| 104 |
|
| 105 |
-
// template<> not used for a member of an
|
| 106 |
-
|
| 107 |
-
void A<int>::f(int) { /* ... */ }
|
| 108 |
|
| 109 |
template<> struct A<char>::B {
|
| 110 |
void f();
|
| 111 |
};
|
| 112 |
-
// template<> also not used when defining a member of
|
| 113 |
-
|
| 114 |
-
void A<char>::B::f() { /* ... */ }
|
| 115 |
|
| 116 |
template<> template<class U> struct A<char>::C {
|
| 117 |
void f();
|
| 118 |
};
|
| 119 |
-
// template<> is used when defining a member of an explicitly
|
| 120 |
-
// specialized
|
| 121 |
template<>
|
| 122 |
-
template<class U> void A<char>::C<U>::f() {
|
| 123 |
|
| 124 |
template<> struct A<short>::B {
|
| 125 |
void f();
|
| 126 |
};
|
| 127 |
-
template<> void A<short>::B::f() {
|
| 128 |
|
| 129 |
template<> template<class U> struct A<short>::C {
|
| 130 |
void f();
|
| 131 |
};
|
| 132 |
-
template<class U> void A<short>::C<U>::f() {
|
| 133 |
```
|
| 134 |
|
|
|
|
|
|
|
| 135 |
If a template, a member template or a member of a class template is
|
| 136 |
explicitly specialized then that specialization shall be declared before
|
| 137 |
the first use of that specialization that would cause an implicit
|
| 138 |
instantiation to take place, in every translation unit in which such a
|
| 139 |
use occurs; no diagnostic is required. If the program does not provide a
|
|
@@ -142,22 +151,22 @@ is used in a way that would cause an implicit instantiation to take
|
|
| 142 |
place or the member is a virtual member function, the program is
|
| 143 |
ill-formed, no diagnostic required. An implicit instantiation is never
|
| 144 |
generated for an explicit specialization that is declared but not
|
| 145 |
defined.
|
| 146 |
|
|
|
|
|
|
|
| 147 |
``` cpp
|
| 148 |
class String { };
|
| 149 |
-
template<class T> class Array {
|
| 150 |
-
template<class T> void sort(Array<T>& v) {
|
| 151 |
|
| 152 |
void f(Array<String>& v) {
|
| 153 |
-
sort(v); // use primary template
|
| 154 |
-
// sort(Array<T>&), T is String
|
| 155 |
}
|
| 156 |
|
| 157 |
-
template<> void sort<String>(Array<String>& v);
|
| 158 |
-
// after use of primary template
|
| 159 |
template<> void sort<>(Array<char*>& v); // OK: sort<char*> not yet used
|
| 160 |
template<class T> struct A {
|
| 161 |
enum E : T;
|
| 162 |
enum class S : T;
|
| 163 |
};
|
|
@@ -168,10 +177,12 @@ template<class T> enum class A<T>::S : T { sT };
|
|
| 168 |
template<> enum A<char>::E : char { echar }; // ill-formed, A<char>::E was instantiated
|
| 169 |
// when A<char> was instantiated
|
| 170 |
template<> enum class A<char>::S : char { schar }; // OK
|
| 171 |
```
|
| 172 |
|
|
|
|
|
|
|
| 173 |
The placement of explicit specialization declarations for function
|
| 174 |
templates, class templates, variable templates, member functions of
|
| 175 |
class templates, static data members of class templates, member classes
|
| 176 |
of class templates, member enumerations of class templates, member class
|
| 177 |
templates of class templates, member function templates of class
|
|
@@ -190,87 +201,108 @@ When writing a specialization, be careful about its location; or to make
|
|
| 190 |
it compile will be such a trial as to kindle its self-immolation.
|
| 191 |
|
| 192 |
A template explicit specialization is in the scope of the namespace in
|
| 193 |
which the template was defined.
|
| 194 |
|
|
|
|
|
|
|
| 195 |
``` cpp
|
| 196 |
namespace N {
|
| 197 |
-
template<class T> class X {
|
| 198 |
-
template<class T> class Y {
|
| 199 |
|
| 200 |
-
template<> class X<int> {
|
| 201 |
-
|
| 202 |
-
template<> class Y<double>; // forward declare intent to
|
| 203 |
-
// specialize for double
|
| 204 |
}
|
| 205 |
|
| 206 |
-
template<> class N::Y<double> {
|
| 207 |
-
|
| 208 |
-
template<> class N::Y<short> { /* ... */ }; // OK: specialization
|
| 209 |
-
// in enclosing namespace
|
| 210 |
```
|
| 211 |
|
|
|
|
|
|
|
| 212 |
A *simple-template-id* that names a class template explicit
|
| 213 |
specialization that has been declared but not defined can be used
|
| 214 |
exactly like the names of other incompletely-defined classes (
|
| 215 |
[[basic.types]]).
|
| 216 |
|
|
|
|
|
|
|
| 217 |
``` cpp
|
| 218 |
template<class T> class X; // X is a class template
|
| 219 |
template<> class X<int>;
|
| 220 |
|
| 221 |
X<int>* p; // OK: pointer to declared class X<int>
|
| 222 |
X<int> x; // error: object of incomplete class X<int>
|
| 223 |
```
|
| 224 |
|
|
|
|
|
|
|
| 225 |
A trailing *template-argument* can be left unspecified in the
|
| 226 |
*template-id* naming an explicit function template specialization
|
| 227 |
provided it can be deduced from the function argument type.
|
| 228 |
|
|
|
|
|
|
|
| 229 |
``` cpp
|
| 230 |
-
template<class T> class Array {
|
| 231 |
template<class T> void sort(Array<T>& v);
|
| 232 |
|
| 233 |
// explicit specialization for sort(Array<int>&)
|
| 234 |
// with deduced template-argument of type int
|
| 235 |
template<> void sort(Array<int>&);
|
| 236 |
```
|
| 237 |
|
|
|
|
|
|
|
| 238 |
A function with the same name as a template and a type that exactly
|
| 239 |
matches that of a template specialization is not an explicit
|
| 240 |
specialization ([[temp.fct]]).
|
| 241 |
|
| 242 |
-
An explicit specialization of a function template is inline
|
| 243 |
-
is declared with the `inline` specifier or defined as
|
| 244 |
-
independently of whether its function
|
|
|
|
|
|
|
|
|
|
| 245 |
|
| 246 |
``` cpp
|
| 247 |
-
template<class T> void f(T) {
|
| 248 |
-
template<class T> inline T g(T) {
|
| 249 |
|
| 250 |
-
template<> inline void f<>(int) {
|
| 251 |
-
template<> int g<>(int) {
|
| 252 |
```
|
| 253 |
|
|
|
|
|
|
|
| 254 |
An explicit specialization of a static data member of a template or an
|
| 255 |
explicit specialization of a static data member template is a definition
|
| 256 |
if the declaration includes an initializer; otherwise, it is a
|
| 257 |
-
declaration.
|
| 258 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 259 |
|
| 260 |
``` cpp
|
| 261 |
template<> X Q<int>::x; // declaration
|
| 262 |
template<> X Q<int>::x (); // error: declares a function
|
| 263 |
template<> X Q<int>::x { }; // definition
|
| 264 |
```
|
| 265 |
|
|
|
|
|
|
|
| 266 |
A member or a member template of a class template may be explicitly
|
| 267 |
specialized for a given implicit instantiation of the class template,
|
| 268 |
even if the member or member template is defined in the class template
|
| 269 |
definition. An explicit specialization of a member or member template is
|
| 270 |
specified using the syntax for explicit specialization.
|
| 271 |
|
|
|
|
|
|
|
| 272 |
``` cpp
|
| 273 |
template<class T> struct A {
|
| 274 |
void f(T);
|
| 275 |
template<class X1> void g1(T, X1);
|
| 276 |
template<class X2> void g2(T, X2);
|
|
@@ -294,37 +326,45 @@ template<> template<>
|
|
| 294 |
|
| 295 |
// member specialization even if defined in class definition
|
| 296 |
template<> void A<int>::h(int) { }
|
| 297 |
```
|
| 298 |
|
|
|
|
|
|
|
| 299 |
A member or a member template may be nested within many enclosing class
|
| 300 |
templates. In an explicit specialization for such a member, the member
|
| 301 |
declaration shall be preceded by a `template<>` for each enclosing class
|
| 302 |
template that is explicitly specialized.
|
| 303 |
|
|
|
|
|
|
|
| 304 |
``` cpp
|
| 305 |
template<class T1> class A {
|
| 306 |
template<class T2> class B {
|
| 307 |
void mf();
|
| 308 |
};
|
| 309 |
};
|
| 310 |
template<> template<> class A<int>::B<double>;
|
| 311 |
template<> template<> void A<char>::B<char>::mf();
|
| 312 |
```
|
| 313 |
|
|
|
|
|
|
|
| 314 |
In an explicit specialization declaration for a member of a class
|
| 315 |
template or a member template that appears in namespace scope, the
|
| 316 |
member template and some of its enclosing class templates may remain
|
| 317 |
unspecialized, except that the declaration shall not explicitly
|
| 318 |
specialize a class member template if its enclosing class templates are
|
| 319 |
not explicitly specialized as well. In such explicit specialization
|
| 320 |
declaration, the keyword `template` followed by a
|
| 321 |
*template-parameter-list* shall be provided instead of the `template<>`
|
| 322 |
preceding the explicit specialization declaration of the member. The
|
| 323 |
-
types of the *template-
|
| 324 |
shall be the same as those specified in the primary template definition.
|
| 325 |
|
|
|
|
|
|
|
| 326 |
``` cpp
|
| 327 |
template <class T1> class A {
|
| 328 |
template<class T2> class B {
|
| 329 |
template<class T3> void mf1(T3);
|
| 330 |
void mf2();
|
|
@@ -339,10 +379,12 @@ template <> template <> template<class T>
|
|
| 339 |
template <class Y> template <>
|
| 340 |
void A<Y>::B<double>::mf2() { } // ill-formed; B<double> is specialized but
|
| 341 |
// its enclosing class template A is not
|
| 342 |
```
|
| 343 |
|
|
|
|
|
|
|
| 344 |
A specialization of a member function template, member class template,
|
| 345 |
or static data member template of a non-specialized class template is
|
| 346 |
itself a template.
|
| 347 |
|
| 348 |
An explicit specialization declaration shall not be a friend
|
|
@@ -353,10 +395,10 @@ definition for one of the following explicit specializations:
|
|
| 353 |
|
| 354 |
- the explicit specialization of a function template;
|
| 355 |
- the explicit specialization of a member function template;
|
| 356 |
- the explicit specialization of a member function of a class template
|
| 357 |
where the class template specialization to which the member function
|
| 358 |
-
specialization belongs is implicitly instantiated.
|
| 359 |
-
arguments may be specified in the declaration or definition
|
| 360 |
-
member function of a class template specialization that is
|
| 361 |
-
specialized.
|
| 362 |
|
|
|
|
| 17 |
``` bnf
|
| 18 |
explicit-specialization:
|
| 19 |
'template < >' declaration
|
| 20 |
```
|
| 21 |
|
| 22 |
+
[*Example 1*:
|
| 23 |
+
|
| 24 |
``` cpp
|
| 25 |
template<class T> class stream;
|
| 26 |
|
| 27 |
+
template<> class stream<char> { ... };
|
| 28 |
|
| 29 |
+
template<class T> class Array { ... };
|
| 30 |
+
template<class T> void sort(Array<T>& v) { ... }
|
| 31 |
|
| 32 |
template<> void sort<char*>(Array<char*>&);
|
| 33 |
```
|
| 34 |
|
| 35 |
Given these declarations, `stream<char>` will be used as the definition
|
|
|
|
| 37 |
specializations instantiated from the class template. Similarly,
|
| 38 |
`sort<char*>` will be used as the sort function for arguments of type
|
| 39 |
`Array<char*>`; other `Array` types will be sorted by functions
|
| 40 |
generated from the template.
|
| 41 |
|
| 42 |
+
— *end example*]
|
| 43 |
+
|
| 44 |
+
An explicit specialization may be declared in any scope in which the
|
| 45 |
+
corresponding primary template may be defined ([[namespace.memdef]],
|
| 46 |
+
[[class.mem]], [[temp.mem]]).
|
|
|
|
|
|
|
|
|
|
| 47 |
|
| 48 |
A declaration of a function template, class template, or variable
|
| 49 |
template being explicitly specialized shall precede the declaration of
|
| 50 |
+
the explicit specialization.
|
| 51 |
+
|
| 52 |
+
[*Note 1*: A declaration, but not a definition of the template is
|
| 53 |
+
required. — *end note*]
|
| 54 |
+
|
| 55 |
+
The definition of a class or class template shall precede the
|
| 56 |
+
declaration of an explicit specialization for a member template of the
|
| 57 |
+
class or class template.
|
| 58 |
+
|
| 59 |
+
[*Example 2*:
|
| 60 |
|
| 61 |
``` cpp
|
| 62 |
+
template<> class X<int> { ... }; // error: X not a template
|
| 63 |
|
| 64 |
template<class T> class X;
|
| 65 |
|
| 66 |
+
template<> class X<char*> { ... }; // OK: X is a template
|
| 67 |
```
|
| 68 |
|
| 69 |
+
— *end example*]
|
| 70 |
+
|
| 71 |
A member function, a member function template, a member class, a member
|
| 72 |
enumeration, a member class template, a static data member, or a static
|
| 73 |
data member template of a class template may be explicitly specialized
|
| 74 |
for a class specialization that is implicitly instantiated; in this
|
| 75 |
case, the definition of the class template shall precede the explicit
|
|
|
|
| 92 |
syntax. The same is true when defining a member of an explicitly
|
| 93 |
specialized member class. However, `template<>` is used in defining a
|
| 94 |
member of an explicitly specialized member class template that is
|
| 95 |
specialized as a class template.
|
| 96 |
|
| 97 |
+
[*Example 3*:
|
| 98 |
+
|
| 99 |
``` cpp
|
| 100 |
template<class T> struct A {
|
| 101 |
struct B { };
|
| 102 |
template<class U> struct C { };
|
| 103 |
};
|
|
|
|
| 109 |
void h() {
|
| 110 |
A<int> a;
|
| 111 |
a.f(16); // A<int>::f must be defined somewhere
|
| 112 |
}
|
| 113 |
|
| 114 |
+
// template<> not used for a member of an explicitly specialized class template
|
| 115 |
+
void A<int>::f(int) { ... }
|
|
|
|
| 116 |
|
| 117 |
template<> struct A<char>::B {
|
| 118 |
void f();
|
| 119 |
};
|
| 120 |
+
// template<> also not used when defining a member of an explicitly specialized member class
|
| 121 |
+
void A<char>::B::f() { ... }
|
|
|
|
| 122 |
|
| 123 |
template<> template<class U> struct A<char>::C {
|
| 124 |
void f();
|
| 125 |
};
|
| 126 |
+
// template<> is used when defining a member of an explicitly specialized member class template
|
| 127 |
+
// specialized as a class template
|
| 128 |
template<>
|
| 129 |
+
template<class U> void A<char>::C<U>::f() { ... }
|
| 130 |
|
| 131 |
template<> struct A<short>::B {
|
| 132 |
void f();
|
| 133 |
};
|
| 134 |
+
template<> void A<short>::B::f() { ... } // error: template<> not permitted
|
| 135 |
|
| 136 |
template<> template<class U> struct A<short>::C {
|
| 137 |
void f();
|
| 138 |
};
|
| 139 |
+
template<class U> void A<short>::C<U>::f() { ... } // error: template<> required
|
| 140 |
```
|
| 141 |
|
| 142 |
+
— *end example*]
|
| 143 |
+
|
| 144 |
If a template, a member template or a member of a class template is
|
| 145 |
explicitly specialized then that specialization shall be declared before
|
| 146 |
the first use of that specialization that would cause an implicit
|
| 147 |
instantiation to take place, in every translation unit in which such a
|
| 148 |
use occurs; no diagnostic is required. If the program does not provide a
|
|
|
|
| 151 |
place or the member is a virtual member function, the program is
|
| 152 |
ill-formed, no diagnostic required. An implicit instantiation is never
|
| 153 |
generated for an explicit specialization that is declared but not
|
| 154 |
defined.
|
| 155 |
|
| 156 |
+
[*Example 4*:
|
| 157 |
+
|
| 158 |
``` cpp
|
| 159 |
class String { };
|
| 160 |
+
template<class T> class Array { ... };
|
| 161 |
+
template<class T> void sort(Array<T>& v) { ... }
|
| 162 |
|
| 163 |
void f(Array<String>& v) {
|
| 164 |
+
sort(v); // use primary template sort(Array<T>&), T is String
|
|
|
|
| 165 |
}
|
| 166 |
|
| 167 |
+
template<> void sort<String>(Array<String>& v); // error: specialization after use of primary template
|
|
|
|
| 168 |
template<> void sort<>(Array<char*>& v); // OK: sort<char*> not yet used
|
| 169 |
template<class T> struct A {
|
| 170 |
enum E : T;
|
| 171 |
enum class S : T;
|
| 172 |
};
|
|
|
|
| 177 |
template<> enum A<char>::E : char { echar }; // ill-formed, A<char>::E was instantiated
|
| 178 |
// when A<char> was instantiated
|
| 179 |
template<> enum class A<char>::S : char { schar }; // OK
|
| 180 |
```
|
| 181 |
|
| 182 |
+
— *end example*]
|
| 183 |
+
|
| 184 |
The placement of explicit specialization declarations for function
|
| 185 |
templates, class templates, variable templates, member functions of
|
| 186 |
class templates, static data members of class templates, member classes
|
| 187 |
of class templates, member enumerations of class templates, member class
|
| 188 |
templates of class templates, member function templates of class
|
|
|
|
| 201 |
it compile will be such a trial as to kindle its self-immolation.
|
| 202 |
|
| 203 |
A template explicit specialization is in the scope of the namespace in
|
| 204 |
which the template was defined.
|
| 205 |
|
| 206 |
+
[*Example 5*:
|
| 207 |
+
|
| 208 |
``` cpp
|
| 209 |
namespace N {
|
| 210 |
+
template<class T> class X { ... };
|
| 211 |
+
template<class T> class Y { ... };
|
| 212 |
|
| 213 |
+
template<> class X<int> { ... }; // OK: specialization in same namespace
|
| 214 |
+
template<> class Y<double>; // forward-declare intent to specialize for double
|
|
|
|
|
|
|
| 215 |
}
|
| 216 |
|
| 217 |
+
template<> class N::Y<double> { ... }; // OK: specialization in enclosing namespace
|
| 218 |
+
template<> class N::Y<short> { ... }; // OK: specialization in enclosing namespace
|
|
|
|
|
|
|
| 219 |
```
|
| 220 |
|
| 221 |
+
— *end example*]
|
| 222 |
+
|
| 223 |
A *simple-template-id* that names a class template explicit
|
| 224 |
specialization that has been declared but not defined can be used
|
| 225 |
exactly like the names of other incompletely-defined classes (
|
| 226 |
[[basic.types]]).
|
| 227 |
|
| 228 |
+
[*Example 6*:
|
| 229 |
+
|
| 230 |
``` cpp
|
| 231 |
template<class T> class X; // X is a class template
|
| 232 |
template<> class X<int>;
|
| 233 |
|
| 234 |
X<int>* p; // OK: pointer to declared class X<int>
|
| 235 |
X<int> x; // error: object of incomplete class X<int>
|
| 236 |
```
|
| 237 |
|
| 238 |
+
— *end example*]
|
| 239 |
+
|
| 240 |
A trailing *template-argument* can be left unspecified in the
|
| 241 |
*template-id* naming an explicit function template specialization
|
| 242 |
provided it can be deduced from the function argument type.
|
| 243 |
|
| 244 |
+
[*Example 7*:
|
| 245 |
+
|
| 246 |
``` cpp
|
| 247 |
+
template<class T> class Array { ... };
|
| 248 |
template<class T> void sort(Array<T>& v);
|
| 249 |
|
| 250 |
// explicit specialization for sort(Array<int>&)
|
| 251 |
// with deduced template-argument of type int
|
| 252 |
template<> void sort(Array<int>&);
|
| 253 |
```
|
| 254 |
|
| 255 |
+
— *end example*]
|
| 256 |
+
|
| 257 |
A function with the same name as a template and a type that exactly
|
| 258 |
matches that of a template specialization is not an explicit
|
| 259 |
specialization ([[temp.fct]]).
|
| 260 |
|
| 261 |
+
An explicit specialization of a function or variable template is inline
|
| 262 |
+
only if it is declared with the `inline` specifier or defined as
|
| 263 |
+
deleted, and independently of whether its function or variable template
|
| 264 |
+
is inline.
|
| 265 |
+
|
| 266 |
+
[*Example 8*:
|
| 267 |
|
| 268 |
``` cpp
|
| 269 |
+
template<class T> void f(T) { ... }
|
| 270 |
+
template<class T> inline T g(T) { ... }
|
| 271 |
|
| 272 |
+
template<> inline void f<>(int) { ... } // OK: inline
|
| 273 |
+
template<> int g<>(int) { ... } // OK: not inline
|
| 274 |
```
|
| 275 |
|
| 276 |
+
— *end example*]
|
| 277 |
+
|
| 278 |
An explicit specialization of a static data member of a template or an
|
| 279 |
explicit specialization of a static data member template is a definition
|
| 280 |
if the declaration includes an initializer; otherwise, it is a
|
| 281 |
+
declaration.
|
| 282 |
+
|
| 283 |
+
[*Note 2*:
|
| 284 |
+
|
| 285 |
+
The definition of a static data member of a template that requires
|
| 286 |
+
default-initialization must use a *braced-init-list*:
|
| 287 |
|
| 288 |
``` cpp
|
| 289 |
template<> X Q<int>::x; // declaration
|
| 290 |
template<> X Q<int>::x (); // error: declares a function
|
| 291 |
template<> X Q<int>::x { }; // definition
|
| 292 |
```
|
| 293 |
|
| 294 |
+
— *end note*]
|
| 295 |
+
|
| 296 |
A member or a member template of a class template may be explicitly
|
| 297 |
specialized for a given implicit instantiation of the class template,
|
| 298 |
even if the member or member template is defined in the class template
|
| 299 |
definition. An explicit specialization of a member or member template is
|
| 300 |
specified using the syntax for explicit specialization.
|
| 301 |
|
| 302 |
+
[*Example 9*:
|
| 303 |
+
|
| 304 |
``` cpp
|
| 305 |
template<class T> struct A {
|
| 306 |
void f(T);
|
| 307 |
template<class X1> void g1(T, X1);
|
| 308 |
template<class X2> void g2(T, X2);
|
|
|
|
| 326 |
|
| 327 |
// member specialization even if defined in class definition
|
| 328 |
template<> void A<int>::h(int) { }
|
| 329 |
```
|
| 330 |
|
| 331 |
+
— *end example*]
|
| 332 |
+
|
| 333 |
A member or a member template may be nested within many enclosing class
|
| 334 |
templates. In an explicit specialization for such a member, the member
|
| 335 |
declaration shall be preceded by a `template<>` for each enclosing class
|
| 336 |
template that is explicitly specialized.
|
| 337 |
|
| 338 |
+
[*Example 10*:
|
| 339 |
+
|
| 340 |
``` cpp
|
| 341 |
template<class T1> class A {
|
| 342 |
template<class T2> class B {
|
| 343 |
void mf();
|
| 344 |
};
|
| 345 |
};
|
| 346 |
template<> template<> class A<int>::B<double>;
|
| 347 |
template<> template<> void A<char>::B<char>::mf();
|
| 348 |
```
|
| 349 |
|
| 350 |
+
— *end example*]
|
| 351 |
+
|
| 352 |
In an explicit specialization declaration for a member of a class
|
| 353 |
template or a member template that appears in namespace scope, the
|
| 354 |
member template and some of its enclosing class templates may remain
|
| 355 |
unspecialized, except that the declaration shall not explicitly
|
| 356 |
specialize a class member template if its enclosing class templates are
|
| 357 |
not explicitly specialized as well. In such explicit specialization
|
| 358 |
declaration, the keyword `template` followed by a
|
| 359 |
*template-parameter-list* shall be provided instead of the `template<>`
|
| 360 |
preceding the explicit specialization declaration of the member. The
|
| 361 |
+
types of the *template-parameter*s in the *template-parameter-list*
|
| 362 |
shall be the same as those specified in the primary template definition.
|
| 363 |
|
| 364 |
+
[*Example 11*:
|
| 365 |
+
|
| 366 |
``` cpp
|
| 367 |
template <class T1> class A {
|
| 368 |
template<class T2> class B {
|
| 369 |
template<class T3> void mf1(T3);
|
| 370 |
void mf2();
|
|
|
|
| 379 |
template <class Y> template <>
|
| 380 |
void A<Y>::B<double>::mf2() { } // ill-formed; B<double> is specialized but
|
| 381 |
// its enclosing class template A is not
|
| 382 |
```
|
| 383 |
|
| 384 |
+
— *end example*]
|
| 385 |
+
|
| 386 |
A specialization of a member function template, member class template,
|
| 387 |
or static data member template of a non-specialized class template is
|
| 388 |
itself a template.
|
| 389 |
|
| 390 |
An explicit specialization declaration shall not be a friend
|
|
|
|
| 395 |
|
| 396 |
- the explicit specialization of a function template;
|
| 397 |
- the explicit specialization of a member function template;
|
| 398 |
- the explicit specialization of a member function of a class template
|
| 399 |
where the class template specialization to which the member function
|
| 400 |
+
specialization belongs is implicitly instantiated. \[*Note 3*: Default
|
| 401 |
+
function arguments may be specified in the declaration or definition
|
| 402 |
+
of a member function of a class template specialization that is
|
| 403 |
+
explicitly specialized. — *end note*]
|
| 404 |
|