Init
This commit is contained in:
220
cppdraft/basic/lookup/argdep.md
Normal file
220
cppdraft/basic/lookup/argdep.md
Normal file
@@ -0,0 +1,220 @@
|
||||
[basic.lookup.argdep]
|
||||
|
||||
# 6 Basics [[basic]](./#basic)
|
||||
|
||||
## 6.5 Name lookup [[basic.lookup]](basic.lookup#argdep)
|
||||
|
||||
### 6.5.4 Argument-dependent name lookup [basic.lookup.argdep]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2100)
|
||||
|
||||
When the [*postfix-expression*](expr.post.general#nt:postfix-expression "7.6.1.1 General [expr.post.general]") in
|
||||
a function call ([[expr.call]](expr.call "7.6.1.3 Function call")) is an [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]"),
|
||||
and unqualified lookup ([[basic.lookup.unqual]](basic.lookup.unqual "6.5.3 Unqualified name lookup"))
|
||||
for the name in the [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") does not find any
|
||||
|
||||
- [(1.1)](#1.1)
|
||||
|
||||
declaration of a class member, or
|
||||
|
||||
- [(1.2)](#1.2)
|
||||
|
||||
function declaration inhabiting a block scope, or
|
||||
|
||||
- [(1.3)](#1.3)
|
||||
|
||||
declaration not of a function or function template
|
||||
|
||||
then lookup for the name also includes the result of[*argument-dependent lookup*](#def:lookup,argument-dependent "6.5.4 Argument-dependent name lookup [basic.lookup.argdep]") in a set of associated namespaces
|
||||
that depends on the types of the arguments
|
||||
(and for type template template arguments, the namespace of the template argument),
|
||||
as specified below[.](#1.sentence-1)
|
||||
|
||||
[*Example [1](#example-1)*: namespace N {struct S { }; void f(S);}void g() { N::S s;
|
||||
f(s); // OK, calls N::f(f)(s); // error: N::f not considered; parentheses prevent argument-dependent lookup} â *end example*]
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2133)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
For purposes of determining
|
||||
(during parsing) whether an expression is a[*postfix-expression*](expr.post.general#nt:postfix-expression "7.6.1.1 General [expr.post.general]") for a function call, the usual name lookup
|
||||
rules apply[.](#2.sentence-1)
|
||||
|
||||
In some cases
|
||||
a name followed by < is treated as a [*template-name*](temp.names#nt:template-name "13.3 Names of template specializations [temp.names]") even though name lookup did not find a [*template-name*](temp.names#nt:template-name "13.3 Names of template specializations [temp.names]") (see [[temp.names]](temp.names "13.3 Names of template specializations"))[.](#2.sentence-2)
|
||||
|
||||
For example,int h;void g();namespace N {struct A {}; template <class T> int f(T); template <class T> int g(T); template <class T> int h(T);}int x = f<N::A>(N::A()); // OK, lookup of f finds nothing, f treated as template nameint y = g<N::A>(N::A()); // OK, lookup of g finds a function, g treated as template nameint z = h<N::A>(N::A()); // error: h< does not begin a [*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]")
|
||||
|
||||
The rules have no effect on the syntactic interpretation of an expression[.](#2.sentence-4)
|
||||
|
||||
For example,typedef int f;namespace N {struct A {friend void f(A &); operator int(); void g(A a) {int i = f(a); // f is the typedef, not the friend function: equivalent to int(a)}};}
|
||||
|
||||
Because the expression is not a function call,
|
||||
argument-dependent name lookup does not apply and
|
||||
the friend function f is not found[.](#2.sentence-6)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2178)
|
||||
|
||||
For each argument type T in the function call,
|
||||
there is a set of zero or more [*associated entities*](#def:entity,associated "6.5.4 Argument-dependent name lookup [basic.lookup.argdep]") to be considered[.](#3.sentence-1)
|
||||
|
||||
The set of entities is determined entirely by
|
||||
the types of the function arguments
|
||||
(and any type template template arguments)[.](#3.sentence-2)
|
||||
|
||||
Any [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]")*s* and [*using-declaration*](namespace.udecl#nt:using-declaration "9.10 The using declaration [namespace.udecl]")*s* used to specify the types
|
||||
do not contribute to this set[.](#3.sentence-3)
|
||||
|
||||
The set of entities
|
||||
is determined in the following way:
|
||||
|
||||
- [(3.1)](#3.1)
|
||||
|
||||
If T is std::meta::info ([[meta.syn]](meta.syn "21.4.1 Header <meta> synopsis")),
|
||||
its associated set of entities is the singleton containing
|
||||
the enumeration type std::meta::operators ([[meta.reflection.operators]](meta.reflection.operators "21.4.5 Operator representations"))[.](#3.1.sentence-1)
|
||||
[*Note [2](#note-2)*:
|
||||
The std::meta::info type is a type alias,
|
||||
so an explicit rule is needed to associate calls
|
||||
whose arguments are reflections with the namespace std::meta[.](#3.1.sentence-2)
|
||||
â *end note*]
|
||||
|
||||
- [(3.2)](#3.2)
|
||||
|
||||
If T is any other fundamental type, its associated set of
|
||||
entities is empty[.](#3.2.sentence-1)
|
||||
|
||||
- [(3.3)](#3.3)
|
||||
|
||||
If T is a class type (including unions),
|
||||
its associated entities are:
|
||||
the class itself;
|
||||
the class of which it is a member, if any;
|
||||
and, if it is a complete type, its direct and indirect base classes[.](#3.3.sentence-1)
|
||||
Furthermore, if T is a class template specialization,
|
||||
its associated entities also include:
|
||||
the entities
|
||||
associated with the types of the template arguments
|
||||
provided for template type parameters;
|
||||
the templates used as type template template arguments; and
|
||||
the classes of which any member templates used as type template template
|
||||
arguments are members[.](#3.3.sentence-2)
|
||||
[*Note [3](#note-3)*:
|
||||
Constant template arguments,
|
||||
variable template template arguments, and
|
||||
concept template arguments
|
||||
do not
|
||||
contribute to the set of associated entities[.](#3.3.sentence-3)
|
||||
â *end note*]
|
||||
|
||||
- [(3.4)](#3.4)
|
||||
|
||||
If T is an enumeration type,
|
||||
its associated entities are T and, if it is a class member, the member's class[.](#3.4.sentence-1)
|
||||
|
||||
- [(3.5)](#3.5)
|
||||
|
||||
If T is a pointer to U or an array of U,
|
||||
its associated entities are those associated with U[.](#3.5.sentence-1)
|
||||
|
||||
- [(3.6)](#3.6)
|
||||
|
||||
If T is a function type, its associated
|
||||
entities are those associated with the function parameter types and those
|
||||
associated with the return type[.](#3.6.sentence-1)
|
||||
|
||||
- [(3.7)](#3.7)
|
||||
|
||||
If T is a pointer to a member function of a classX, its associated entities are those associated
|
||||
with the function parameter types and return type, together with those
|
||||
associated with X[.](#3.7.sentence-1)
|
||||
|
||||
- [(3.8)](#3.8)
|
||||
|
||||
If T is a pointer to a data member of class X, its
|
||||
associated entities are those associated with the member
|
||||
type together with those associated with X[.](#3.8.sentence-1)
|
||||
|
||||
In addition, if the argument is an overload set or the address of such a set,
|
||||
its associated entities
|
||||
are the union of those associated with each of the
|
||||
members of the set, i.e., the entities associated with its
|
||||
parameter types and return type[.](#3.sentence-5)
|
||||
|
||||
Additionally, if the aforementioned overload set is named with
|
||||
a [*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]"), its associated entities also include
|
||||
its template template arguments and
|
||||
those associated with its type template arguments[.](#3.sentence-6)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2254)
|
||||
|
||||
The [*associated namespaces*](#def:associated_namespaces) for a call are
|
||||
the innermost enclosing non-inline namespaces for its associated entities
|
||||
as well as every element of the inline namespace set ([[namespace.def]](namespace.def "9.9.2 Namespace definition"))
|
||||
of those namespaces[.](#4.sentence-1)
|
||||
|
||||
Argument-dependent lookup finds
|
||||
all declarations of functions and function templates that
|
||||
|
||||
- [(4.1)](#4.1)
|
||||
|
||||
are found by a search of any associated namespace, or
|
||||
|
||||
- [(4.2)](#4.2)
|
||||
|
||||
are declared as a friend ([[class.friend]](class.friend "11.8.4 Friends")) of any class
|
||||
with a reachable definition in the set of associated entities, or
|
||||
|
||||
- [(4.3)](#4.3)
|
||||
|
||||
are exported,
|
||||
are attached to a named module M ([[module.interface]](module.interface "10.2 Export declaration")),
|
||||
do not appear in the translation unit containing the point of the lookup, and
|
||||
have the same innermost enclosing non-inline namespace scope as
|
||||
a declaration of an associated entity attached to M ([[basic.link]](basic.link "6.7 Program and linkage"))[.](#4.sentence-2)
|
||||
|
||||
If the lookup is for a dependent name ([[temp.dep]](temp.dep "13.8.3 Dependent names"), [[temp.dep.candidate]](temp.dep.candidate "13.8.4.2 Candidate functions")),
|
||||
the above lookup is also performed
|
||||
from each point in the instantiation context ([[module.context]](module.context "10.6 Instantiation context")) of the lookup,
|
||||
additionally ignoring any declaration that
|
||||
appears in another translation unit,
|
||||
is attached to the global module, and
|
||||
is either discarded ([[module.global.frag]](module.global.frag "10.4 Global module fragment")) or has internal linkage[.](#4.sentence-3)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2282)
|
||||
|
||||
[*Example [2](#example-2)*:
|
||||
|
||||
Translation unit #1:export module M;namespace R {export struct X {}; export void f(X);}namespace S {export void f(R::X, R::X);}
|
||||
|
||||
Translation unit #2:export module N;import M;export R::X make();namespace R { static int g(X); }export template<typename T, typename U> void apply(T t, U u) { f(t, u);
|
||||
g(t);}
|
||||
|
||||
Translation unit #3:module Q;import N;namespace S {struct Z { template<typename T> operator T(); };}void test() {auto x = make(); // OK, decltype(x) is R::X in module M R::f(x); // error: R and R::f are not visible here f(x); // OK, calls R::f from interface of M f(x, S::Z()); // error: S::f in module M not considered// even though S is an associated namespace apply(x, S::Z()); // error: S::f is visible in instantiation context, but// R::g has internal linkage and cannot be used outside TU #2} â *end example*]
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2324)
|
||||
|
||||
[*Note [4](#note-4)*:
|
||||
|
||||
The associated namespace can include namespaces
|
||||
already considered by ordinary unqualified lookup[.](#6.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[*Example [3](#example-3)*: namespace NS {class T { }; void f(T); void g(T, int);} NS::T parm;void g(NS::T, float);int main() { f(parm); // OK, calls NS::fextern void g(NS::T, float);
|
||||
g(parm, 1); // OK, calls g(NS::T, float)} â *end example*]
|
||||
46
cppdraft/basic/lookup/elab.md
Normal file
46
cppdraft/basic/lookup/elab.md
Normal file
@@ -0,0 +1,46 @@
|
||||
[basic.lookup.elab]
|
||||
|
||||
# 6 Basics [[basic]](./#basic)
|
||||
|
||||
## 6.5 Name lookup [[basic.lookup]](basic.lookup#elab)
|
||||
|
||||
### 6.5.6 Elaborated type specifiers [basic.lookup.elab]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2745)
|
||||
|
||||
If the [*class-key*](class.pre#nt:class-key "11.1 Preamble [class.pre]") or enum keyword
|
||||
in an [*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]") is followed by an [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") that is not followed by ::,
|
||||
lookup for the [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") is type-only ([[basic.lookup.general]](basic.lookup.general "6.5.1 General"))[.](#1.sentence-1)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
In general, the recognition of an [*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]") depends on the following tokens[.](#1.sentence-2)
|
||||
|
||||
If the [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") is followed by ::,
|
||||
see [[basic.lookup.qual]](basic.lookup.qual "6.5.5 Qualified name lookup")[.](#1.sentence-3)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2758)
|
||||
|
||||
If the terminal name of the [*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]") is a qualified name,
|
||||
lookup for it is type-only[.](#2.sentence-1)
|
||||
|
||||
If the name lookup does not find a previously declared [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]"),
|
||||
the [*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]") is ill-formed[.](#2.sentence-2)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2765)
|
||||
|
||||
[*Example [1](#example-1)*: struct Node {struct Node* Next; // OK, refers to injected-class-name Nodestruct Data* Data; // OK, declares type Data at global scope and member Data};
|
||||
|
||||
struct Data {struct Node* Node; // OK, refers to Node at global scopefriend struct ::Glob; // error: Glob is not declared, cannot introduce a qualified type ([[dcl.type.elab]](dcl.type.elab "9.2.9.5 Elaborated type specifiers"))friend struct Glob; // OK, refers to (as yet) undeclared Glob at global scope./* ... */};
|
||||
|
||||
struct Base {struct Data; // OK, declares nested Datastruct ::Data* thatData; // OK, refers to ::Datastruct Base::Data* thisData; // OK, refers to nested Datafriend class ::Data; // OK, global Data is a friendfriend class Data; // OK, nested Data is a friendstruct Data { /* ... */ }; // Defines nested Data};
|
||||
|
||||
struct Data; // OK, redeclares Data at global scopestruct ::Data; // error: cannot introduce a qualified type ([[dcl.type.elab]](dcl.type.elab "9.2.9.5 Elaborated type specifiers"))struct Base::Data; // error: cannot introduce a qualified type ([[dcl.type.elab]](dcl.type.elab "9.2.9.5 Elaborated type specifiers"))struct Base::Datum; // error: Datum undefinedstruct Base::Data* pBase; // OK, refers to nested Data â *end example*]
|
||||
126
cppdraft/basic/lookup/general.md
Normal file
126
cppdraft/basic/lookup/general.md
Normal file
@@ -0,0 +1,126 @@
|
||||
[basic.lookup.general]
|
||||
|
||||
# 6 Basics [[basic]](./#basic)
|
||||
|
||||
## 6.5 Name lookup [[basic.lookup]](basic.lookup#general)
|
||||
|
||||
### 6.5.1 General [basic.lookup.general]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1624)
|
||||
|
||||
[*Name lookup*](#def:lookup,name "6.5.1 General [basic.lookup.general]") associates the use of a name
|
||||
with a set of declarations ([[basic.def]](basic.def "6.2 Declarations and definitions")) of that name[.](#1.sentence-1)
|
||||
|
||||
The name lookup rules apply uniformly to all names (including[*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]")*s* ([[dcl.typedef]](dcl.typedef "9.2.4 The typedef specifier")),[*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1 General [namespace.def.general]")*s* ([[basic.namespace]](basic.namespace "9.9 Namespaces")), and[*class-name*](class.pre#nt:class-name "11.1 Preamble [class.pre]")*s* ([[class.name]](class.name "11.3 Class names"))) wherever the grammar allows
|
||||
such names in the context discussed by a particular rule[.](#1.sentence-2)
|
||||
|
||||
Unless otherwise specified,
|
||||
the program is ill-formed if no declarations are found[.](#1.sentence-3)
|
||||
|
||||
If the declarations found by name lookup
|
||||
all denote functions or function templates,
|
||||
the declarations are said to form an [*overload set*](#def:overload_set "6.5.1 General [basic.lookup.general]")[.](#1.sentence-4)
|
||||
|
||||
Otherwise,
|
||||
if the declarations found by name lookup do not all denote the same entity,they are [*ambiguous*](#def:ambiguous "6.5.1 General [basic.lookup.general]") and the program is ill-formed[.](#1.sentence-5)
|
||||
|
||||
Overload resolution ([[over.match]](over.match "12.2 Overload resolution"), [[over.over]](over.over "12.3 Address of an overload set"))
|
||||
takes place after name lookup has succeeded[.](#1.sentence-6)
|
||||
|
||||
The access rules ([[class.access]](class.access "11.8 Member access control"))
|
||||
are considered only once name lookup and
|
||||
function overload resolution (if applicable) have succeeded[.](#1.sentence-7)
|
||||
|
||||
Only after
|
||||
name lookup, function overload resolution (if applicable) and access
|
||||
checking have succeeded
|
||||
are the semantic properties introduced by the declarations
|
||||
used in further processing[.](#1.sentence-8)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1650)
|
||||
|
||||
A program point P is said to follow
|
||||
any declaration in the same translation unit
|
||||
whose locus ([[basic.scope.pdecl]](basic.scope.pdecl "6.4.2 Point of declaration")) is before P[.](#2.sentence-1)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
The declaration might appear in a scope that does not contain P[.](#2.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
A declaration X [*precedes*](#def:declaration,precede "6.5.1 General [basic.lookup.general]") a program point P in a translation unit L if P follows X, X inhabits a class scope and is reachable from P, or
|
||||
else X appears in a translation unit D and
|
||||
|
||||
- [(2.1)](#2.1)
|
||||
|
||||
P follows
|
||||
a [*module-import-declaration*](module.import#nt:module-import-declaration "10.3 Import declaration [module.import]") or [*module-declaration*](module.unit#nt:module-declaration "10.1 Module units and purviews [module.unit]") that imports D (directly or indirectly), and
|
||||
|
||||
- [(2.2)](#2.2)
|
||||
|
||||
X appears after the [*module-declaration*](module.unit#nt:module-declaration "10.1 Module units and purviews [module.unit]") in D (if any) and
|
||||
before the [*private-module-fragment*](module.private.frag#nt:private-module-fragment "10.5 Private module fragment [module.private.frag]") in D (if any), and
|
||||
|
||||
- [(2.3)](#2.3)
|
||||
|
||||
either X is exported or else D and L are part of the same module andX does not inhabit a namespace with internal linkage or
|
||||
declare a name with internal linkage[.](#2.sentence-3)
|
||||
[*Note [2](#note-2)*:
|
||||
Names declared by a [*using-declaration*](namespace.udecl#nt:using-declaration "9.10 The using declaration [namespace.udecl]") have no linkage[.](#2.3.sentence-2)
|
||||
â *end note*]
|
||||
|
||||
[*Note [3](#note-3)*:
|
||||
|
||||
A [*module-import-declaration*](module.import#nt:module-import-declaration "10.3 Import declaration [module.import]") imports both
|
||||
the named translation unit(s) and
|
||||
any modules named by exported[*module-import-declaration*](module.import#nt:module-import-declaration "10.3 Import declaration [module.import]")*s* within them,
|
||||
recursively[.](#2.sentence-4)
|
||||
|
||||
[*Example [1](#example-1)*:
|
||||
|
||||
Translation unit #1:export module Q;export int sq(int i) { return i*i; }
|
||||
|
||||
Translation unit #2:export module R;export import Q;
|
||||
|
||||
Translation unit #3:import R;int main() { return sq(9); } // OK, sq from module Q â *end example*]
|
||||
|
||||
â *end note*]
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1702)
|
||||
|
||||
A [*single search*](#def:search,single "6.5.1 General [basic.lookup.general]") in a scope S for a name N from a program point P finds all declarations that precede P to which any name that is the same as N ([[basic.pre]](basic.pre "6.1 Preamble")) is bound in S[.](#3.sentence-1)
|
||||
|
||||
If any such declaration is a [*using-declarator*](namespace.udecl#nt:using-declarator "9.10 The using declaration [namespace.udecl]") whose terminal name ([[expr.prim.id.unqual]](expr.prim.id.unqual "7.5.5.2 Unqualified names"))
|
||||
is not dependent ([[temp.dep.type]](temp.dep.type "13.8.3.2 Dependent types")),
|
||||
it is replaced by the declarations named by
|
||||
the [*using-declarator*](namespace.udecl#nt:using-declarator "9.10 The using declaration [namespace.udecl]") ([[namespace.udecl]](namespace.udecl "9.10 The using declaration"))[.](#3.sentence-2)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1714)
|
||||
|
||||
In certain contexts, only certain kinds of declarations are included[.](#4.sentence-1)
|
||||
|
||||
After any such restriction, any declarations of classes or enumerations are discarded if any other declarations are found[.](#4.sentence-2)
|
||||
|
||||
[*Note [4](#note-4)*:
|
||||
|
||||
A type (but not a type alias or template)
|
||||
is therefore hidden by any other entity in its scope[.](#4.sentence-3)
|
||||
|
||||
â *end note*]
|
||||
|
||||
However, if a lookup is [*type-only*](#def:lookup,type-only "6.5.1 General [basic.lookup.general]"),
|
||||
only declarations of
|
||||
types and templates whose specializations are types are considered;
|
||||
furthermore, if declarations
|
||||
of a type alias and of its underlying entity are found,
|
||||
the declaration of the type alias is discarded
|
||||
instead of the type declaration[.](#4.sentence-4)
|
||||
259
cppdraft/basic/lookup/qual.md
Normal file
259
cppdraft/basic/lookup/qual.md
Normal file
@@ -0,0 +1,259 @@
|
||||
[basic.lookup.qual]
|
||||
|
||||
# 6 Basics [[basic]](./#basic)
|
||||
|
||||
## 6.5 Name lookup [[basic.lookup]](basic.lookup#qual)
|
||||
|
||||
### 6.5.5 Qualified name lookup [basic.lookup.qual]
|
||||
|
||||
#### [6.5.5.1](#general) General [[basic.lookup.qual.general]](basic.lookup.qual.general)
|
||||
|
||||
[1](#general-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2350)
|
||||
|
||||
Lookup of an [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") followed by a :: scope resolution operator
|
||||
considers only
|
||||
namespaces, types, and templates whose specializations are types[.](#general-1.sentence-1)
|
||||
|
||||
If a
|
||||
name,[*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]"),[*splice-scope-specifier*](expr.prim.id.qual#nt:splice-scope-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]"), or[*computed-type-specifier*](dcl.type.simple#nt:computed-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]") is followed by a ::,
|
||||
it shall either be
|
||||
a dependent [*splice-scope-specifier*](expr.prim.id.qual#nt:splice-scope-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") ([[temp.dep.splice]](temp.dep.splice "13.8.3.5 Dependent splice specifiers")) or
|
||||
it shall designate a namespace, class, enumeration, or dependent type,
|
||||
and the :: is never interpreted as
|
||||
a complete [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]")[.](#general-1.sentence-2)
|
||||
|
||||
[*Example [1](#general-example-1)*: class A {public:static int n;};int main() {int A;
|
||||
A::n = 42; // OK A b; // error: A does not name a type}template<int> struct B : A {};namespace N {template<int> void B(); int f() {return B<0>::n; // error: N::B<0> is not a type}} â *end example*]
|
||||
|
||||
[2](#general-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2393)
|
||||
|
||||
A member-qualified name is
|
||||
the (unique) component name ([[expr.prim.id.unqual]](expr.prim.id.unqual "7.5.5.2 Unqualified names")), if any, of
|
||||
|
||||
- [(2.1)](#general-2.1)
|
||||
|
||||
an [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") or
|
||||
|
||||
- [(2.2)](#general-2.2)
|
||||
|
||||
a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") of the form[*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]") :: or [*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1 General [namespace.def.general]") ::
|
||||
|
||||
in the [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") of a class member access expression ([[expr.ref]](expr.ref "7.6.1.5 Class member access"))[.](#general-2.sentence-1)
|
||||
|
||||
A [*qualified name*](#def:name,qualified "6.5.5.1 General [basic.lookup.qual.general]") is
|
||||
|
||||
- [(2.3)](#general-2.3)
|
||||
|
||||
a member-qualified name or
|
||||
|
||||
- [(2.4)](#general-2.4)
|
||||
|
||||
the terminal name of
|
||||
* [(2.4.1)](#general-2.4.1)
|
||||
|
||||
a [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]"),
|
||||
|
||||
* [(2.4.2)](#general-2.4.2)
|
||||
|
||||
a [*using-declarator*](namespace.udecl#nt:using-declarator "9.10 The using declaration [namespace.udecl]"),
|
||||
|
||||
* [(2.4.3)](#general-2.4.3)
|
||||
|
||||
a [*typename-specifier*](temp.res.general#nt:typename-specifier "13.8.1 General [temp.res.general]"),
|
||||
|
||||
* [(2.4.4)](#general-2.4.4)
|
||||
|
||||
a [*qualified-namespace-specifier*](namespace.alias#nt:qualified-namespace-specifier "9.9.3 Namespace alias [namespace.alias]"), or
|
||||
|
||||
* [(2.4.5)](#general-2.4.5)
|
||||
|
||||
a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]"),[*reflection-name*](expr.reflect#nt:reflection-name "7.6.2.10 The reflection operator [expr.reflect]"),[*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]"), or[*class-or-decltype*](class.derived.general#nt:class-or-decltype "11.7.1 General [class.derived.general]") that has a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") ([[expr.prim.id.qual]](expr.prim.id.qual "7.5.5.3 Qualified names"))[.](#general-2.sentence-2)
|
||||
|
||||
The [*lookup context*](#def:lookup_context "6.5.5.1 General [basic.lookup.qual.general]") of a member-qualified name is
|
||||
the type of its associated object expression
|
||||
(considered dependent if the object expression is type-dependent)[.](#general-2.sentence-3)
|
||||
|
||||
The lookup context of any other qualified name is
|
||||
the type, template, or namespace
|
||||
nominated by the preceding [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]")[.](#general-2.sentence-4)
|
||||
|
||||
[*Note [1](#general-note-1)*:
|
||||
|
||||
When parsing a class member access,
|
||||
the name following the -> or . is
|
||||
a qualified name even though it is not yet known of which kind[.](#general-2.sentence-5)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[*Example [2](#general-example-2)*:
|
||||
|
||||
In N::C::m.Base::f()Base is a member-qualified name;
|
||||
the other qualified names are C, m, and f[.](#general-2.sentence-6)
|
||||
|
||||
â *end example*]
|
||||
|
||||
[3](#general-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2440)
|
||||
|
||||
[*Qualified name lookup*](#def:lookup,qualified_name "6.5.5.1 General [basic.lookup.qual.general]") in a class, namespace, or enumeration performs
|
||||
a search of the scope associated with it ([[class.member.lookup]](class.member.lookup "6.5.2 Member name lookup"))
|
||||
except as specified below[.](#general-3.sentence-1)
|
||||
|
||||
Unless otherwise specified,
|
||||
a qualified name undergoes qualified name lookup in its lookup context
|
||||
from the point where it appears
|
||||
unless the lookup context either
|
||||
is dependent and is not the current instantiation ([[temp.dep.type]](temp.dep.type "13.8.3.2 Dependent types")) or
|
||||
is not a class or class template[.](#general-3.sentence-2)
|
||||
|
||||
If nothing is found by qualified lookup for a member-qualified name
|
||||
that is the terminal name ([[expr.prim.id.unqual]](expr.prim.id.unqual "7.5.5.2 Unqualified names")) of
|
||||
a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") and
|
||||
is not dependent, it undergoes unqualified lookup[.](#general-3.sentence-3)
|
||||
|
||||
[*Note [2](#general-note-2)*:
|
||||
|
||||
During lookup for a template specialization, no names are dependent[.](#general-3.sentence-4)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[*Example [3](#general-example-3)*: int f();struct A {int B, C; template<int> using D = void; using T = void; void f();};using B = A;template<int> using C = A;template<int> using D = A;template<int> using X = A;
|
||||
|
||||
template<class T>void g(T *p) { // as instantiated for g<A>: p->X<0>::f(); // error: A::X not found in ((p->X) < 0) > ::f() p->template X<0>::f(); // OK, ::X found in definition context p->B::f(); // OK, non-type A::B ignored p->template C<0>::f(); // error: A::C is not a template p->template D<0>::f(); // error: A::D<0> is not a class type p->T::f(); // error: A::T is not a class type}template void g(A*); â *end example*]
|
||||
|
||||
[4](#general-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2485)
|
||||
|
||||
If a qualified name Q follows a ~:
|
||||
|
||||
- [(4.1)](#general-4.1)
|
||||
|
||||
If Q is a member-qualified name,
|
||||
it undergoes unqualified lookup as well as qualified lookup[.](#general-4.1.sentence-1)
|
||||
|
||||
- [(4.2)](#general-4.2)
|
||||
|
||||
Otherwise, its [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") N shall nominate a type[.](#general-4.2.sentence-1)
|
||||
If N has another [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") S,Q is looked up as if its lookup context were that nominated by S[.](#general-4.2.sentence-2)
|
||||
|
||||
- [(4.3)](#general-4.3)
|
||||
|
||||
Otherwise, if the terminal name of N is a member-qualified name M,Q is looked up as if ~Q appeared in place of M (as above)[.](#general-4.3.sentence-1)
|
||||
|
||||
- [(4.4)](#general-4.4)
|
||||
|
||||
Otherwise, Q undergoes unqualified lookup[.](#general-4.4.sentence-1)
|
||||
|
||||
- [(4.5)](#general-4.5)
|
||||
|
||||
Each lookup for Q considers only
|
||||
types (if Q is not followed by a <) and
|
||||
templates whose specializations are types[.](#general-4.5.sentence-1)
|
||||
If it finds nothing or is ambiguous, it is discarded[.](#general-4.5.sentence-2)
|
||||
|
||||
- [(4.6)](#general-4.6)
|
||||
|
||||
The [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]") that is or contains Q shall refer to its (original) lookup context (ignoring cv-qualification) under
|
||||
the interpretation established by at least one (successful) lookup performed[.](#general-4.6.sentence-1)
|
||||
|
||||
[*Example [4](#general-example-4)*: struct C {typedef int I;};typedef int I1, I2;extern int* p;extern int* q;void f() { p->C::I::~I(); // I is looked up in the scope of C q->I1::~I2(); // I2 is found by unqualified lookup}struct A {~A();};typedef A AB;int main() { AB* p;
|
||||
p->AB::~AB(); // explicitly calls the destructor for A} â *end example*]
|
||||
|
||||
#### [6.5.5.2](#class.qual) Class members [[class.qual]](class.qual)
|
||||
|
||||
[1](#class.qual-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2537)
|
||||
|
||||
In a lookup for a qualified name N whose lookup context is a class C in which function names are not ignored,[18](#footnote-18 "Lookups in which function names are ignored include names appearing in a nested-name-specifier, an elaborated-type-specifier, or a base-specifier.")
|
||||
|
||||
- [(1.1)](#class.qual-1.1)
|
||||
|
||||
if the search finds the injected-class-name of C ([[class.pre]](class.pre "11.1 Preamble")), or
|
||||
|
||||
- [(1.2)](#class.qual-1.2)
|
||||
|
||||
if N is dependent and
|
||||
is the terminal name of a [*using-declarator*](namespace.udecl#nt:using-declarator "9.10 The using declaration [namespace.udecl]") ([[namespace.udecl]](namespace.udecl "9.10 The using declaration"))
|
||||
that names a constructor,
|
||||
|
||||
N is instead considered to name the constructor of class C[.](#class.qual-1.sentence-1)
|
||||
|
||||
Such a constructor name shall be used only
|
||||
in the [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") of a (friend) declaration of a constructor or
|
||||
in a [*using-declaration*](namespace.udecl#nt:using-declaration "9.10 The using declaration [namespace.udecl]")[.](#class.qual-1.sentence-2)
|
||||
|
||||
[*Example [1](#class.qual-example-1)*: struct A { A(); };struct B: public A { B(); };
|
||||
|
||||
A::A() { } B::B() { } B::A ba; // object of type A A::A a; // error: A::A is not a type namestruct A::A a2; // object of type A â *end example*]
|
||||
|
||||
[18)](#footnote-18)[18)](#footnoteref-18)
|
||||
|
||||
Lookups in which
|
||||
function names are ignored include names appearing in a[*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]"), an[*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]"), or a [*base-specifier*](class.derived.general#nt:base-specifier "11.7.1 General [class.derived.general]")[.](#footnote-18.sentence-1)
|
||||
|
||||
#### [6.5.5.3](#namespace.qual) Namespace members [[namespace.qual]](namespace.qual)
|
||||
|
||||
[1](#namespace.qual-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2574)
|
||||
|
||||
Qualified name lookup in a namespace N additionally searches
|
||||
every element of the inline namespace set of N ([[namespace.def]](namespace.def "9.9.2 Namespace definition"))[.](#namespace.qual-1.sentence-1)
|
||||
|
||||
If nothing is found,
|
||||
the results of the lookup are the results of qualified name lookup
|
||||
in each namespace nominated by a [*using-directive*](namespace.udir#nt:using-directive "9.9.4 Using namespace directive [namespace.udir]") that precedes the point of the lookup and
|
||||
inhabits N or an element of N's inline namespace set[.](#namespace.qual-1.sentence-2)
|
||||
|
||||
[*Note [1](#namespace.qual-note-1)*:
|
||||
|
||||
If a [*using-directive*](namespace.udir#nt:using-directive "9.9.4 Using namespace directive [namespace.udir]") refers to a namespace
|
||||
that has already been considered, it does not affect the result[.](#namespace.qual-1.sentence-3)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[*Example [1](#namespace.qual-example-1)*: int x;namespace Y {void f(float); void h(int);}namespace Z {void h(double);}namespace A {using namespace Y; void f(int); void g(int); int i;}namespace B {using namespace Z; void f(char); int i;}namespace AB {using namespace A; using namespace B; void g();}void h(){ AB::g(); // g is declared directly in AB, therefore S is { AB::g() } and AB::g() is chosen AB::f(1); // f is not declared directly in AB so the rules are applied recursively to A and B;// namespace Y is not searched and Y::f(float) is not considered;// S is { A::f(int), B::f(char) } and overload resolution chooses A::f(int) AB::f('c'); // as above but resolution chooses B::f(char) AB::x++; // x is not declared directly in AB, and is not declared in A or B, so the rules// are applied recursively to Y and Z, S is { } so the program is ill-formed AB::i++; // i is not declared directly in AB so the rules are applied recursively to A and B,// S is { A::i, B::i } so the use is ambiguous and the program is ill-formed AB::h(16.8); // h is not declared directly in AB and not declared directly in A or B so the rules// are applied recursively to Y and Z, S is { Y::h(int), Z::h(double) } and// overload resolution chooses Z::h(double)} â *end example*]
|
||||
|
||||
[2](#namespace.qual-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2640)
|
||||
|
||||
[*Note [2](#namespace.qual-note-2)*:
|
||||
|
||||
The same declaration found more than once is not an ambiguity (because
|
||||
it is still a unique declaration)[.](#namespace.qual-2.sentence-1)
|
||||
|
||||
[*Example [2](#namespace.qual-example-2)*: namespace A {int a;}namespace B {using namespace A;}namespace C {using namespace A;}namespace BC {using namespace B; using namespace C;}void f(){ BC::a++; // OK, S is { A::a, A::a }}namespace D {using A::a;}namespace BD {using namespace B; using namespace D;}void g(){ BD::a++; // OK, S is { A::a, A::a }} â *end example*]
|
||||
|
||||
â *end note*]
|
||||
|
||||
[3](#namespace.qual-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2685)
|
||||
|
||||
[*Example [3](#namespace.qual-example-3)*:
|
||||
|
||||
Because each referenced namespace is searched at most once, the
|
||||
following is well-defined:namespace B {int b;}namespace A {using namespace B; int a;}namespace B {using namespace A;}void f(){ A::a++; // OK, a declared directly in A, S is { A::a } B::a++; // OK, both A and B searched (once), S is { A::a } A::b++; // OK, both A and B searched (once), S is { B::b } B::b++; // OK, b declared directly in B, S is { B::b }}
|
||||
|
||||
â *end example*]
|
||||
|
||||
[4](#namespace.qual-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2713)
|
||||
|
||||
[*Note [3](#namespace.qual-note-3)*:
|
||||
|
||||
Class and enumeration declarations are not discarded
|
||||
because of other declarations found in other searches[.](#namespace.qual-4.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[*Example [4](#namespace.qual-example-4)*: namespace A {struct x { }; int x; int y;}namespace B {struct y { };}namespace C {using namespace A; using namespace B; int i = C::x; // OK, A::x (of type int)int j = C::y; // ambiguous, A::y or B::y} â *end example*]
|
||||
166
cppdraft/basic/lookup/qual/general.md
Normal file
166
cppdraft/basic/lookup/qual/general.md
Normal file
@@ -0,0 +1,166 @@
|
||||
[basic.lookup.qual.general]
|
||||
|
||||
# 6 Basics [[basic]](./#basic)
|
||||
|
||||
## 6.5 Name lookup [[basic.lookup]](basic.lookup#qual.general)
|
||||
|
||||
### 6.5.5 Qualified name lookup [[basic.lookup.qual]](basic.lookup.qual#general)
|
||||
|
||||
#### 6.5.5.1 General [basic.lookup.qual.general]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2350)
|
||||
|
||||
Lookup of an [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") followed by a :: scope resolution operator
|
||||
considers only
|
||||
namespaces, types, and templates whose specializations are types[.](#1.sentence-1)
|
||||
|
||||
If a
|
||||
name,[*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]"),[*splice-scope-specifier*](expr.prim.id.qual#nt:splice-scope-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]"), or[*computed-type-specifier*](dcl.type.simple#nt:computed-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]") is followed by a ::,
|
||||
it shall either be
|
||||
a dependent [*splice-scope-specifier*](expr.prim.id.qual#nt:splice-scope-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") ([[temp.dep.splice]](temp.dep.splice "13.8.3.5 Dependent splice specifiers")) or
|
||||
it shall designate a namespace, class, enumeration, or dependent type,
|
||||
and the :: is never interpreted as
|
||||
a complete [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]")[.](#1.sentence-2)
|
||||
|
||||
[*Example [1](#example-1)*: class A {public:static int n;};int main() {int A;
|
||||
A::n = 42; // OK A b; // error: A does not name a type}template<int> struct B : A {};namespace N {template<int> void B(); int f() {return B<0>::n; // error: N::B<0> is not a type}} â *end example*]
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2393)
|
||||
|
||||
A member-qualified name is
|
||||
the (unique) component name ([[expr.prim.id.unqual]](expr.prim.id.unqual "7.5.5.2 Unqualified names")), if any, of
|
||||
|
||||
- [(2.1)](#2.1)
|
||||
|
||||
an [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") or
|
||||
|
||||
- [(2.2)](#2.2)
|
||||
|
||||
a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") of the form[*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]") :: or [*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1 General [namespace.def.general]") ::
|
||||
|
||||
in the [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") of a class member access expression ([[expr.ref]](expr.ref "7.6.1.5 Class member access"))[.](#2.sentence-1)
|
||||
|
||||
A [*qualified name*](#def:name,qualified "6.5.5.1 General [basic.lookup.qual.general]") is
|
||||
|
||||
- [(2.3)](#2.3)
|
||||
|
||||
a member-qualified name or
|
||||
|
||||
- [(2.4)](#2.4)
|
||||
|
||||
the terminal name of
|
||||
* [(2.4.1)](#2.4.1)
|
||||
|
||||
a [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]"),
|
||||
|
||||
* [(2.4.2)](#2.4.2)
|
||||
|
||||
a [*using-declarator*](namespace.udecl#nt:using-declarator "9.10 The using declaration [namespace.udecl]"),
|
||||
|
||||
* [(2.4.3)](#2.4.3)
|
||||
|
||||
a [*typename-specifier*](temp.res.general#nt:typename-specifier "13.8.1 General [temp.res.general]"),
|
||||
|
||||
* [(2.4.4)](#2.4.4)
|
||||
|
||||
a [*qualified-namespace-specifier*](namespace.alias#nt:qualified-namespace-specifier "9.9.3 Namespace alias [namespace.alias]"), or
|
||||
|
||||
* [(2.4.5)](#2.4.5)
|
||||
|
||||
a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]"),[*reflection-name*](expr.reflect#nt:reflection-name "7.6.2.10 The reflection operator [expr.reflect]"),[*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]"), or[*class-or-decltype*](class.derived.general#nt:class-or-decltype "11.7.1 General [class.derived.general]") that has a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") ([[expr.prim.id.qual]](expr.prim.id.qual "7.5.5.3 Qualified names"))[.](#2.sentence-2)
|
||||
|
||||
The [*lookup context*](#def:lookup_context "6.5.5.1 General [basic.lookup.qual.general]") of a member-qualified name is
|
||||
the type of its associated object expression
|
||||
(considered dependent if the object expression is type-dependent)[.](#2.sentence-3)
|
||||
|
||||
The lookup context of any other qualified name is
|
||||
the type, template, or namespace
|
||||
nominated by the preceding [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]")[.](#2.sentence-4)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
When parsing a class member access,
|
||||
the name following the -> or . is
|
||||
a qualified name even though it is not yet known of which kind[.](#2.sentence-5)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[*Example [2](#example-2)*:
|
||||
|
||||
In N::C::m.Base::f()Base is a member-qualified name;
|
||||
the other qualified names are C, m, and f[.](#2.sentence-6)
|
||||
|
||||
â *end example*]
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2440)
|
||||
|
||||
[*Qualified name lookup*](#def:lookup,qualified_name "6.5.5.1 General [basic.lookup.qual.general]") in a class, namespace, or enumeration performs
|
||||
a search of the scope associated with it ([[class.member.lookup]](class.member.lookup "6.5.2 Member name lookup"))
|
||||
except as specified below[.](#3.sentence-1)
|
||||
|
||||
Unless otherwise specified,
|
||||
a qualified name undergoes qualified name lookup in its lookup context
|
||||
from the point where it appears
|
||||
unless the lookup context either
|
||||
is dependent and is not the current instantiation ([[temp.dep.type]](temp.dep.type "13.8.3.2 Dependent types")) or
|
||||
is not a class or class template[.](#3.sentence-2)
|
||||
|
||||
If nothing is found by qualified lookup for a member-qualified name
|
||||
that is the terminal name ([[expr.prim.id.unqual]](expr.prim.id.unqual "7.5.5.2 Unqualified names")) of
|
||||
a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") and
|
||||
is not dependent, it undergoes unqualified lookup[.](#3.sentence-3)
|
||||
|
||||
[*Note [2](#note-2)*:
|
||||
|
||||
During lookup for a template specialization, no names are dependent[.](#3.sentence-4)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[*Example [3](#example-3)*: int f();struct A {int B, C; template<int> using D = void; using T = void; void f();};using B = A;template<int> using C = A;template<int> using D = A;template<int> using X = A;
|
||||
|
||||
template<class T>void g(T *p) { // as instantiated for g<A>: p->X<0>::f(); // error: A::X not found in ((p->X) < 0) > ::f() p->template X<0>::f(); // OK, ::X found in definition context p->B::f(); // OK, non-type A::B ignored p->template C<0>::f(); // error: A::C is not a template p->template D<0>::f(); // error: A::D<0> is not a class type p->T::f(); // error: A::T is not a class type}template void g(A*); â *end example*]
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2485)
|
||||
|
||||
If a qualified name Q follows a ~:
|
||||
|
||||
- [(4.1)](#4.1)
|
||||
|
||||
If Q is a member-qualified name,
|
||||
it undergoes unqualified lookup as well as qualified lookup[.](#4.1.sentence-1)
|
||||
|
||||
- [(4.2)](#4.2)
|
||||
|
||||
Otherwise, its [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") N shall nominate a type[.](#4.2.sentence-1)
|
||||
If N has another [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") S,Q is looked up as if its lookup context were that nominated by S[.](#4.2.sentence-2)
|
||||
|
||||
- [(4.3)](#4.3)
|
||||
|
||||
Otherwise, if the terminal name of N is a member-qualified name M,Q is looked up as if ~Q appeared in place of M (as above)[.](#4.3.sentence-1)
|
||||
|
||||
- [(4.4)](#4.4)
|
||||
|
||||
Otherwise, Q undergoes unqualified lookup[.](#4.4.sentence-1)
|
||||
|
||||
- [(4.5)](#4.5)
|
||||
|
||||
Each lookup for Q considers only
|
||||
types (if Q is not followed by a <) and
|
||||
templates whose specializations are types[.](#4.5.sentence-1)
|
||||
If it finds nothing or is ambiguous, it is discarded[.](#4.5.sentence-2)
|
||||
|
||||
- [(4.6)](#4.6)
|
||||
|
||||
The [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]") that is or contains Q shall refer to its (original) lookup context (ignoring cv-qualification) under
|
||||
the interpretation established by at least one (successful) lookup performed[.](#4.6.sentence-1)
|
||||
|
||||
[*Example [4](#example-4)*: struct C {typedef int I;};typedef int I1, I2;extern int* p;extern int* q;void f() { p->C::I::~I(); // I is looked up in the scope of C q->I1::~I2(); // I2 is found by unqualified lookup}struct A {~A();};typedef A AB;int main() { AB* p;
|
||||
p->AB::~AB(); // explicitly calls the destructor for A} â *end example*]
|
||||
14
cppdraft/basic/lookup/udir.md
Normal file
14
cppdraft/basic/lookup/udir.md
Normal file
@@ -0,0 +1,14 @@
|
||||
[basic.lookup.udir]
|
||||
|
||||
# 6 Basics [[basic]](./#basic)
|
||||
|
||||
## 6.5 Name lookup [[basic.lookup]](basic.lookup#udir)
|
||||
|
||||
### 6.5.7 Using-directives and namespace aliases [basic.lookup.udir]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2800)
|
||||
|
||||
In a [*using-directive*](namespace.udir#nt:using-directive "9.9.4 Using namespace directive [namespace.udir]") or [*namespace-alias-definition*](namespace.alias#nt:namespace-alias-definition "9.9.3 Namespace alias [namespace.alias]"),
|
||||
during the lookup for a [*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1 General [namespace.def.general]") or for a name in a[*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") only namespace names are considered[.](#1.sentence-1)
|
||||
100
cppdraft/basic/lookup/unqual.md
Normal file
100
cppdraft/basic/lookup/unqual.md
Normal file
@@ -0,0 +1,100 @@
|
||||
[basic.lookup.unqual]
|
||||
|
||||
# 6 Basics [[basic]](./#basic)
|
||||
|
||||
## 6.5 Name lookup [[basic.lookup]](basic.lookup#unqual)
|
||||
|
||||
### 6.5.3 Unqualified name lookup [basic.lookup.unqual]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1972)
|
||||
|
||||
A [*using-directive*](namespace.udir#nt:using-directive "9.9.4 Using namespace directive [namespace.udir]") is[*active*](#def:active) in a scope S at a program point P if it precedes P and inhabits either S or
|
||||
the scope of a namespace nominated by a [*using-directive*](namespace.udir#nt:using-directive "9.9.4 Using namespace directive [namespace.udir]") that is active in S at P[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1979)
|
||||
|
||||
An [*unqualified search*](#def:unqualified_search) in a scope S from a program point P includes the results of searches from P in
|
||||
|
||||
- [(2.1)](#2.1)
|
||||
|
||||
S, and
|
||||
|
||||
- [(2.2)](#2.2)
|
||||
|
||||
for any scope U that contains P and is or is contained by S,
|
||||
each namespace contained by S that is nominated by
|
||||
a [*using-directive*](namespace.udir#nt:using-directive "9.9.4 Using namespace directive [namespace.udir]") that is active in U at P[.](#2.sentence-1)
|
||||
|
||||
If no declarations are found,
|
||||
the results of the unqualified search are
|
||||
the results of an unqualified search in the parent scope of S, if any,
|
||||
from P[.](#2.sentence-2)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
When a class scope is searched,
|
||||
the scopes of its base classes are also searched ([[class.member.lookup]](class.member.lookup "6.5.2 Member name lookup"))[.](#2.sentence-3)
|
||||
|
||||
If it inherits from a single base,
|
||||
it is as if the scope of the base immediately contains
|
||||
the scope of the derived class[.](#2.sentence-4)
|
||||
|
||||
Template parameter scopes
|
||||
that are associated with one scope in the chain of parents
|
||||
are also considered ([[temp.local]](temp.local "13.8.2 Locally declared names"))[.](#2.sentence-5)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2005)
|
||||
|
||||
[*Unqualified name lookup*](#def:lookup,unqualified_name "6.5.3 Unqualified name lookup [basic.lookup.unqual]") from a program point performs an unqualified search in its immediate scope[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2009)
|
||||
|
||||
An [*unqualified name*](#def:name,unqualified "6.5.3 Unqualified name lookup [basic.lookup.unqual]") is a name
|
||||
that does not immediately follow a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") or
|
||||
the . or -> in a class member access expression ([[expr.ref]](expr.ref "7.6.1.5 Class member access")),
|
||||
possibly after a template keyword or ~[.](#4.sentence-1)
|
||||
|
||||
Unless otherwise specified,
|
||||
such a name undergoes unqualified name lookup from the point where it appears[.](#4.sentence-2)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2017)
|
||||
|
||||
An unqualified name that is a component name ([[expr.prim.id.unqual]](expr.prim.id.unqual "7.5.5.2 Unqualified names")) of
|
||||
a [*type-specifier*](dcl.type.general#nt:type-specifier "9.2.9.1 General [dcl.type.general]") or [*ptr-operator*](dcl.decl.general#nt:ptr-operator "9.3.1 General [dcl.decl.general]") of
|
||||
a [*conversion-type-id*](class.conv.fct#nt:conversion-type-id "11.4.8.3 Conversion functions [class.conv.fct]") is looked up in the same fashion
|
||||
as the [*conversion-function-id*](class.conv.fct#nt:conversion-function-id "11.4.8.3 Conversion functions [class.conv.fct]") in which it appears[.](#5.sentence-1)
|
||||
|
||||
If that lookup finds nothing, it undergoes unqualified name lookup;
|
||||
in each case, only names
|
||||
that denote types or templates whose specializations are types are considered[.](#5.sentence-2)
|
||||
|
||||
[*Example [1](#example-1)*: struct T1 { struct U { int i; }; };struct T2 { };struct U1 {};struct U2 {};
|
||||
|
||||
struct B {using T = T1; using U = U1; operator U1 T1::*(); operator U1 T2::*(); operator U2 T1::*(); operator U2 T2::*();};
|
||||
|
||||
template<class X, class T>int g() {using U = U2;
|
||||
X().operator U T::*(); // #1, searches for T in the scope of X first X().operator U decltype(T())::*(); // #2return 0;}int x = g<B, T2>(); // #1 calls B::operator U1 T1::*// #2 calls B::operator U1 T2::* â *end example*]
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2053)
|
||||
|
||||
In a friend declaration [*declarator*](dcl.decl.general#nt:declarator "9.3.1 General [dcl.decl.general]") whose [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") is a [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") whose lookup context ([[basic.lookup.qual]](basic.lookup.qual "6.5.5 Qualified name lookup")) is a class or namespace S,
|
||||
lookup for an unqualified name
|
||||
that appears after the [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") performs a search in the scope associated with S[.](#6.sentence-1)
|
||||
|
||||
If that lookup finds nothing, it undergoes unqualified name lookup[.](#6.sentence-2)
|
||||
|
||||
[*Example [2](#example-2)*: using I = int;using D = double;namespace A {inline namespace N {using C = char; }using F = float; void f(I); void f(D); void f(C); void f(F);}struct X0 {using F = float; };struct W {using D = void; struct X : X0 {void g(I); void g(::D); void g(F); };};namespace B {typedef short I, F; class Y {friend void A::f(I); // error: no void A::f(short)friend void A::f(D); // OKfriend void A::f(C); // error: A::N::C not foundfriend void A::f(F); // OKfriend void W::X::g(I); // error: no void X::g(short)friend void W::X::g(D); // OKfriend void W::X::g(F); // OK};} â *end example*]
|
||||
Reference in New Issue
Block a user