From Jason Turner

[basic.lookup.qual.general]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpoc_i7gyx/{from.md → to.md} +160 -0
tmp/tmpoc_i7gyx/{from.md → to.md} RENAMED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #### General <a id="basic.lookup.qual.general">[[basic.lookup.qual.general]]</a>
2
+
3
+ Lookup of an *identifier* followed by a `::` scope resolution operator
4
+ considers only namespaces, types, and templates whose specializations
5
+ are types. If a name, *template-id*, or *decltype-specifier* is followed
6
+ by a `::`, it shall designate a namespace, class, enumeration, or
7
+ dependent type, and the `::` is never interpreted as a complete
8
+ *nested-name-specifier*.
9
+
10
+ [*Example 1*:
11
+
12
+ ``` cpp
13
+ class A {
14
+ public:
15
+ static int n;
16
+ };
17
+ int main() {
18
+ int A;
19
+ A::n = 42; // OK
20
+ A b; // error: A does not name a type
21
+ }
22
+ template<int> struct B : A {};
23
+ namespace N {
24
+ template<int> void B();
25
+ int f() {
26
+ return B<0>::n; // error: N::B<0> is not a type
27
+ }
28
+ }
29
+ ```
30
+
31
+ — *end example*]
32
+
33
+ A member-qualified name is the (unique) component name
34
+ [[expr.prim.id.unqual]], if any, of
35
+
36
+ - an *unqualified-id* or
37
+ - a *nested-name-specifier* of the form *type-name* `::` or
38
+ *namespace-name* `::`
39
+
40
+ in the *id-expression* of a class member access expression [[expr.ref]].
41
+ A *qualified name* is
42
+
43
+ - a member-qualified name or
44
+ - the terminal name of
45
+ - a *qualified-id*,
46
+ - a *using-declarator*,
47
+ - a *typename-specifier*,
48
+ - a *qualified-namespace-specifier*, or
49
+ - a *nested-name-specifier*, *elaborated-type-specifier*, or
50
+ *class-or-decltype* that has a *nested-name-specifier*
51
+ [[expr.prim.id.qual]].
52
+
53
+ The *lookup context* of a member-qualified name is the type of its
54
+ associated object expression (considered dependent if the object
55
+ expression is type-dependent). The lookup context of any other qualified
56
+ name is the type, template, or namespace nominated by the preceding
57
+ *nested-name-specifier*.
58
+
59
+ [*Note 1*: When parsing a class member access, the name following the
60
+ `->` or `.` is a qualified name even though it is not yet known of which
61
+ kind. — *end note*]
62
+
63
+ [*Example 2*:
64
+
65
+ In
66
+
67
+ ``` cpp
68
+ N::C::m.Base::f()
69
+ ```
70
+
71
+ `Base` is a member-qualified name; the other qualified names are `C`,
72
+ `m`, and `f`.
73
+
74
+ — *end example*]
75
+
76
+ *Qualified name lookup* in a class, namespace, or enumeration performs a
77
+ search of the scope associated with it [[class.member.lookup]] except as
78
+ specified below. Unless otherwise specified, a qualified name undergoes
79
+ qualified name lookup in its lookup context from the point where it
80
+ appears unless the lookup context either is dependent and is not the
81
+ current instantiation [[temp.dep.type]] or is not a class or class
82
+ template. If nothing is found by qualified lookup for a member-qualified
83
+ name that is the terminal name [[expr.prim.id.unqual]] of a
84
+ *nested-name-specifier* and is not dependent, it undergoes unqualified
85
+ lookup.
86
+
87
+ [*Note 2*: During lookup for a template specialization, no names are
88
+ dependent. — *end note*]
89
+
90
+ [*Example 3*:
91
+
92
+ ``` cpp
93
+ int f();
94
+ struct A {
95
+ int B, C;
96
+ template<int> using D = void;
97
+ using T = void;
98
+ void f();
99
+ };
100
+ using B = A;
101
+ template<int> using C = A;
102
+ template<int> using D = A;
103
+ template<int> using X = A;
104
+
105
+ template<class T>
106
+ void g(T *p) { // as instantiated for g<A>:
107
+ p->X<0>::f(); // error: A::X not found in ((p->X) < 0) > ::f()
108
+ p->template X<0>::f(); // OK, ::X found in definition context
109
+ p->B::f(); // OK, non-type A::B ignored
110
+ p->template C<0>::f(); // error: A::C is not a template
111
+ p->template D<0>::f(); // error: A::D<0> is not a class type
112
+ p->T::f(); // error: A::T is not a class type
113
+ }
114
+ template void g(A*);
115
+ ```
116
+
117
+ — *end example*]
118
+
119
+ If a qualified name Q follows a `~`:
120
+
121
+ - If Q is a member-qualified name, it undergoes unqualified lookup as
122
+ well as qualified lookup.
123
+ - Otherwise, its *nested-name-specifier* N shall nominate a type. If N
124
+ has another *nested-name-specifier* S, Q is looked up as if its lookup
125
+ context were that nominated by S.
126
+ - Otherwise, if the terminal name of N is a member-qualified name M, Q
127
+ is looked up as if `\~`Q appeared in place of M (as above).
128
+ - Otherwise, Q undergoes unqualified lookup.
129
+ - Each lookup for Q considers only types (if Q is not followed by a `<`)
130
+ and templates whose specializations are types. If it finds nothing or
131
+ is ambiguous, it is discarded.
132
+ - The *type-name* that is or contains Q shall refer to its (original)
133
+ lookup context (ignoring cv-qualification) under the interpretation
134
+ established by at least one (successful) lookup performed.
135
+
136
+ [*Example 4*:
137
+
138
+ ``` cpp
139
+ struct C {
140
+ typedef int I;
141
+ };
142
+ typedef int I1, I2;
143
+ extern int* p;
144
+ extern int* q;
145
+ void f() {
146
+ p->C::I::~I(); // I is looked up in the scope of C
147
+ q->I1::~I2(); // I2 is found by unqualified lookup
148
+ }
149
+ struct A {
150
+ ~A();
151
+ };
152
+ typedef A AB;
153
+ int main() {
154
+ AB* p;
155
+ p->AB::~AB(); // explicitly calls the destructor for A
156
+ }
157
+ ```
158
+
159
+ — *end example*]
160
+