tmp/tmp715c0p_i/{from.md → to.md}
RENAMED
|
@@ -14,10 +14,12 @@ Within the scope of a class template specialization or partial
|
|
| 14 |
specialization, when the injected-class-name is used as a *type-name*,
|
| 15 |
it is equivalent to the *template-name* followed by the
|
| 16 |
*template-argument*s of the class template specialization or partial
|
| 17 |
specialization enclosed in `<>`.
|
| 18 |
|
|
|
|
|
|
|
| 19 |
``` cpp
|
| 20 |
template<template<class> class T> class A { };
|
| 21 |
template<class T> class Y;
|
| 22 |
template<> class Y<int> {
|
| 23 |
Y* p; // meaning Y<int>
|
|
@@ -27,14 +29,18 @@ template<> class Y<int> {
|
|
| 27 |
template<class> friend class Y; // meaning ::Y
|
| 28 |
};
|
| 29 |
};
|
| 30 |
```
|
| 31 |
|
|
|
|
|
|
|
| 32 |
The injected-class-name of a class template or class template
|
| 33 |
specialization can be used either as a *template-name* or a *type-name*
|
| 34 |
wherever it is in scope.
|
| 35 |
|
|
|
|
|
|
|
| 36 |
``` cpp
|
| 37 |
template <class T> struct Base {
|
| 38 |
Base* p;
|
| 39 |
};
|
| 40 |
|
|
@@ -44,43 +50,55 @@ template <class T> struct Derived: public Base<T> {
|
|
| 44 |
|
| 45 |
template<class T, template<class> class U = T::template Base> struct Third { };
|
| 46 |
Third<Base<int> > t; // OK: default argument uses injected-class-name as a template
|
| 47 |
```
|
| 48 |
|
|
|
|
|
|
|
| 49 |
A lookup that finds an injected-class-name ([[class.member.lookup]])
|
| 50 |
can result in an ambiguity in certain cases (for example, if it is found
|
| 51 |
in more than one base class). If all of the injected-class-names that
|
| 52 |
are found refer to specializations of the same class template, and if
|
| 53 |
the name is used as a *template-name*, the reference refers to the class
|
| 54 |
template itself and not a specialization thereof, and is not ambiguous.
|
| 55 |
|
|
|
|
|
|
|
| 56 |
``` cpp
|
| 57 |
template <class T> struct Base { };
|
| 58 |
template <class T> struct Derived: Base<int>, Base<char> {
|
| 59 |
typename Derived::Base b; // error: ambiguous
|
| 60 |
typename Derived::Base<double> d; // OK
|
| 61 |
};
|
| 62 |
```
|
| 63 |
|
|
|
|
|
|
|
| 64 |
When the normal name of the template (i.e., the name from the enclosing
|
| 65 |
scope, not the injected-class-name) is used, it always refers to the
|
| 66 |
class template itself and not a specialization of the template.
|
| 67 |
|
|
|
|
|
|
|
| 68 |
``` cpp
|
| 69 |
template<class T> class X {
|
| 70 |
X* p; // meaning X<T>
|
| 71 |
X<T>* p2;
|
| 72 |
X<int>* p3;
|
| 73 |
::X* p4; // error: missing template argument list
|
| 74 |
// ::X does not refer to the injected-class-name
|
| 75 |
};
|
| 76 |
```
|
| 77 |
|
|
|
|
|
|
|
| 78 |
A *template-parameter* shall not be redeclared within its scope
|
| 79 |
(including nested scopes). A *template-parameter* shall not have the
|
| 80 |
same name as the template name.
|
| 81 |
|
|
|
|
|
|
|
| 82 |
``` cpp
|
| 83 |
template<class T, int i> class Y {
|
| 84 |
int T; // error: template-parameter redeclared
|
| 85 |
void f() {
|
| 86 |
char T; // error: template-parameter redeclared
|
|
@@ -88,19 +106,23 @@ template<class T, int i> class Y {
|
|
| 88 |
};
|
| 89 |
|
| 90 |
template<class X> class X; // error: template-parameter redeclared
|
| 91 |
```
|
| 92 |
|
|
|
|
|
|
|
| 93 |
In the definition of a member of a class template that appears outside
|
| 94 |
of the class template definition, the name of a member of the class
|
| 95 |
template hides the name of a *template-parameter* of any enclosing class
|
| 96 |
templates (but not a *template-parameter* of the member if the member is
|
| 97 |
a class or function template).
|
| 98 |
|
|
|
|
|
|
|
| 99 |
``` cpp
|
| 100 |
template<class T> struct A {
|
| 101 |
-
struct B {
|
| 102 |
typedef void C;
|
| 103 |
void f();
|
| 104 |
template<class U> void g(U);
|
| 105 |
};
|
| 106 |
|
|
@@ -112,14 +134,18 @@ template<class B> template<class C> void A<B>::g(C) {
|
|
| 112 |
B b; // A's B, not the template parameter
|
| 113 |
C c; // the template parameter C, not A's C
|
| 114 |
}
|
| 115 |
```
|
| 116 |
|
|
|
|
|
|
|
| 117 |
In the definition of a member of a class template that appears outside
|
| 118 |
of the namespace containing the class template definition, the name of a
|
| 119 |
*template-parameter* hides the name of a member of this namespace.
|
| 120 |
|
|
|
|
|
|
|
| 121 |
``` cpp
|
| 122 |
namespace N {
|
| 123 |
class C { };
|
| 124 |
template<class T> class B {
|
| 125 |
void f(T);
|
|
@@ -128,26 +154,31 @@ namespace N {
|
|
| 128 |
template<class C> void N::B<C>::f(C) {
|
| 129 |
C b; // C is the template parameter, not N::C
|
| 130 |
}
|
| 131 |
```
|
| 132 |
|
|
|
|
|
|
|
| 133 |
In the definition of a class template or in the definition of a member
|
| 134 |
of such a template that appears outside of the template definition, for
|
| 135 |
-
each base class
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
|
|
|
| 140 |
|
| 141 |
``` cpp
|
| 142 |
struct A {
|
| 143 |
-
struct B {
|
| 144 |
int a;
|
| 145 |
int Y;
|
| 146 |
};
|
| 147 |
|
| 148 |
template<class B, class a> struct X : A {
|
| 149 |
B b; // A's B
|
| 150 |
a b; // error: A's a isn't a type name
|
| 151 |
};
|
| 152 |
```
|
| 153 |
|
|
|
|
|
|
|
|
|
| 14 |
specialization, when the injected-class-name is used as a *type-name*,
|
| 15 |
it is equivalent to the *template-name* followed by the
|
| 16 |
*template-argument*s of the class template specialization or partial
|
| 17 |
specialization enclosed in `<>`.
|
| 18 |
|
| 19 |
+
[*Example 1*:
|
| 20 |
+
|
| 21 |
``` cpp
|
| 22 |
template<template<class> class T> class A { };
|
| 23 |
template<class T> class Y;
|
| 24 |
template<> class Y<int> {
|
| 25 |
Y* p; // meaning Y<int>
|
|
|
|
| 29 |
template<class> friend class Y; // meaning ::Y
|
| 30 |
};
|
| 31 |
};
|
| 32 |
```
|
| 33 |
|
| 34 |
+
— *end example*]
|
| 35 |
+
|
| 36 |
The injected-class-name of a class template or class template
|
| 37 |
specialization can be used either as a *template-name* or a *type-name*
|
| 38 |
wherever it is in scope.
|
| 39 |
|
| 40 |
+
[*Example 2*:
|
| 41 |
+
|
| 42 |
``` cpp
|
| 43 |
template <class T> struct Base {
|
| 44 |
Base* p;
|
| 45 |
};
|
| 46 |
|
|
|
|
| 50 |
|
| 51 |
template<class T, template<class> class U = T::template Base> struct Third { };
|
| 52 |
Third<Base<int> > t; // OK: default argument uses injected-class-name as a template
|
| 53 |
```
|
| 54 |
|
| 55 |
+
— *end example*]
|
| 56 |
+
|
| 57 |
A lookup that finds an injected-class-name ([[class.member.lookup]])
|
| 58 |
can result in an ambiguity in certain cases (for example, if it is found
|
| 59 |
in more than one base class). If all of the injected-class-names that
|
| 60 |
are found refer to specializations of the same class template, and if
|
| 61 |
the name is used as a *template-name*, the reference refers to the class
|
| 62 |
template itself and not a specialization thereof, and is not ambiguous.
|
| 63 |
|
| 64 |
+
[*Example 3*:
|
| 65 |
+
|
| 66 |
``` cpp
|
| 67 |
template <class T> struct Base { };
|
| 68 |
template <class T> struct Derived: Base<int>, Base<char> {
|
| 69 |
typename Derived::Base b; // error: ambiguous
|
| 70 |
typename Derived::Base<double> d; // OK
|
| 71 |
};
|
| 72 |
```
|
| 73 |
|
| 74 |
+
— *end example*]
|
| 75 |
+
|
| 76 |
When the normal name of the template (i.e., the name from the enclosing
|
| 77 |
scope, not the injected-class-name) is used, it always refers to the
|
| 78 |
class template itself and not a specialization of the template.
|
| 79 |
|
| 80 |
+
[*Example 4*:
|
| 81 |
+
|
| 82 |
``` cpp
|
| 83 |
template<class T> class X {
|
| 84 |
X* p; // meaning X<T>
|
| 85 |
X<T>* p2;
|
| 86 |
X<int>* p3;
|
| 87 |
::X* p4; // error: missing template argument list
|
| 88 |
// ::X does not refer to the injected-class-name
|
| 89 |
};
|
| 90 |
```
|
| 91 |
|
| 92 |
+
— *end example*]
|
| 93 |
+
|
| 94 |
A *template-parameter* shall not be redeclared within its scope
|
| 95 |
(including nested scopes). A *template-parameter* shall not have the
|
| 96 |
same name as the template name.
|
| 97 |
|
| 98 |
+
[*Example 5*:
|
| 99 |
+
|
| 100 |
``` cpp
|
| 101 |
template<class T, int i> class Y {
|
| 102 |
int T; // error: template-parameter redeclared
|
| 103 |
void f() {
|
| 104 |
char T; // error: template-parameter redeclared
|
|
|
|
| 106 |
};
|
| 107 |
|
| 108 |
template<class X> class X; // error: template-parameter redeclared
|
| 109 |
```
|
| 110 |
|
| 111 |
+
— *end example*]
|
| 112 |
+
|
| 113 |
In the definition of a member of a class template that appears outside
|
| 114 |
of the class template definition, the name of a member of the class
|
| 115 |
template hides the name of a *template-parameter* of any enclosing class
|
| 116 |
templates (but not a *template-parameter* of the member if the member is
|
| 117 |
a class or function template).
|
| 118 |
|
| 119 |
+
[*Example 6*:
|
| 120 |
+
|
| 121 |
``` cpp
|
| 122 |
template<class T> struct A {
|
| 123 |
+
struct B { ... };
|
| 124 |
typedef void C;
|
| 125 |
void f();
|
| 126 |
template<class U> void g(U);
|
| 127 |
};
|
| 128 |
|
|
|
|
| 134 |
B b; // A's B, not the template parameter
|
| 135 |
C c; // the template parameter C, not A's C
|
| 136 |
}
|
| 137 |
```
|
| 138 |
|
| 139 |
+
— *end example*]
|
| 140 |
+
|
| 141 |
In the definition of a member of a class template that appears outside
|
| 142 |
of the namespace containing the class template definition, the name of a
|
| 143 |
*template-parameter* hides the name of a member of this namespace.
|
| 144 |
|
| 145 |
+
[*Example 7*:
|
| 146 |
+
|
| 147 |
``` cpp
|
| 148 |
namespace N {
|
| 149 |
class C { };
|
| 150 |
template<class T> class B {
|
| 151 |
void f(T);
|
|
|
|
| 154 |
template<class C> void N::B<C>::f(C) {
|
| 155 |
C b; // C is the template parameter, not N::C
|
| 156 |
}
|
| 157 |
```
|
| 158 |
|
| 159 |
+
— *end example*]
|
| 160 |
+
|
| 161 |
In the definition of a class template or in the definition of a member
|
| 162 |
of such a template that appears outside of the template definition, for
|
| 163 |
+
each non-dependent base class ([[temp.dep.type]]), if the name of the
|
| 164 |
+
base class or the name of a member of the base class is the same as the
|
| 165 |
+
name of a *template-parameter*, the base class name or member name hides
|
| 166 |
+
the *template-parameter* name ([[basic.scope.hiding]]).
|
| 167 |
+
|
| 168 |
+
[*Example 8*:
|
| 169 |
|
| 170 |
``` cpp
|
| 171 |
struct A {
|
| 172 |
+
struct B { ... };
|
| 173 |
int a;
|
| 174 |
int Y;
|
| 175 |
};
|
| 176 |
|
| 177 |
template<class B, class a> struct X : A {
|
| 178 |
B b; // A's B
|
| 179 |
a b; // error: A's a isn't a type name
|
| 180 |
};
|
| 181 |
```
|
| 182 |
|
| 183 |
+
— *end example*]
|
| 184 |
+
|