Date
2017-02-06.00:00:00
Message id
115

Content

From paper J16/99-0010 = WG21 N1187.

_N4567_.5.1.1 [expr.prim.general] paragraph 7 says that class-name::class-name names the constructor when both class-name refer to the same class. (Note the different perspective, at least, in 11.4.5 [class.ctor] paragraph 1, in which constructors have no names and are recognized by syntactic context rather than by name.)

This formulation does not address the case of classes in which a function 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 argument list is for the injected class name or for the constructor.

Suggested resolution: restate the rule as a component of name lookup. Specifically, if when doing a qualified lookup in a given class 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. For example:

    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. For example, if the injected class name could be qualified by its own class 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 member has redundant parentheses, and it's only after seeing the declarator that the parser can know that the second A<int> is the injected class name rather than the constructor.