Created on1999-02-21.00:00:00 last changed277 months ago
Proposed resolution (10/00):
InClause 11 [class] paragraph 2, change
Theclass-name is also inserted into the scope of the classitself. For purposes of access checking the inserted class name...
to
Theclass-name is also inserted into the scope of the classitself; this is known as theinjected-class-name. For purposesof access checking, the injected-class-name...
Also, in 6.5.5.2 [class.qual], add the followingbefore paragraph 2:
If thenested-name-specifier nominates a classC, and thename specified after thenested-name-specifier, when looked up inC, is the injected-class-name ofC (Clause 11 [class]), the name is instead consideredto name the constructor of classC. Such a constructor nameshall only be used in thedeclarator-id of a constructordefinition that appears outside of the class definition.[Example: 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 name—end example]Also, change 6.5 [basic.lookup] paragraph 3 from
Because the name of a class is inserted in its class scope (Clause 11 [class]), the name of a class is also considered amember of that class for the purposes of name hiding and lookup.
to
The injected-class-name of a class (Clause 11 [class]) isalso considered to be a member of that class for the purposes of namehiding and lookup.
(See alsoissue 194.)
From paper J16/99-0010 = WG21 N1187.
_N4567_.5.1.1 [expr.prim.general] paragraph 7says thatclass-name::class-name names the constructor when bothclass-name refer to the same class. (Note the differentperspective, at least, in11.4.5 [class.ctor] paragraph 1, in whichconstructors have no names and are recognized by syntactic contextrather than by name.)
This formulation does not address the case of classes in which afunction template is declared as a constructor, for example:
template <class T> struct A { template <class T2> A(T2); }; template<> template<> A<int>::A<int>(int);Here there is an ambiguity as to whether the second template argumentlist is for the injected class name or for the constructor.
Suggested resolution: restate the rule as a component of namelookup. Specifically, if when doing a qualified lookup in a givenclass you look up a name that is the same as the name of the class,the entity found is the constructor and not the injected class name.In all other cases, the name found is the injected class name. Forexample:
class B { }; class A: public B { A::B ab; // B is the inherited injected B A::A aa; // Error: A::A is the constructor };Without this rule some very nasty backtracking is needed. Forexample, if the injected class name could be qualified by its ownclass name, the following code would be well-formed:
template <class T> struct A { template <class T2> A(T2); static A x; }; template<> A<int>::A<int>(A<int>::x);Here the declarator for the definition of the static data memberhas redundant parentheses, and it's only after seeing the declaratorthat the parser can know that the secondA<int> is theinjected class name rather than the constructor.
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2003-04-25 00:00:00 | admin | set | status: dr -> tc1 |
| 2000-11-18 00:00:00 | admin | set | status: ready -> dr |
| 2000-05-21 00:00:00 | admin | set | status: review -> ready |
| 2000-02-23 00:00:00 | admin | set | messages: +msg217 |
| 2000-02-23 00:00:00 | admin | set | status: open -> review |
| 1999-02-21 00:00:00 | admin | create | |