This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 114b. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-05-06


548. qualified-ids in declarations

Section: 9.3.4  [dcl.meaning]     Status: dup     Submitter: Martin Sebor     Date: 18 November 2005

According to 9.3.4 [dcl.meaning] paragraph 1, the declarator in the definition or explicit instantiation of a namespace member can only be qualified if the definition or explicit instantiation appears outside the member's namespace:

A declarator-id shall not be qualified except for the definition of a member function (11.4.2 [class.mfct]) or static data member (11.4.9 [class.static]) outside of its class, the definition or explicit instantiation of a function or variable member of a namespace outside of its namespace, or the definition of a previously declared explicit specialization outside of its namespace, or the declaration of a friend function that is a member of another class or namespace (11.8.4 [class.friend]). When the declarator-id is qualified, the declaration shall refer to a previously declared member of the class or namespace to which the qualifier refers, and the member shall not have been introduced by a using-declaration in the scope of the class or namespace nominated by the nested-name-specifier of the declarator-id.

There is no similar restriction on a qualified-id in a class definition (Clause 11 [class] paragraph 5):

If a class-head contains a nested-name-specifier, the class-specifier shall refer to a class that was previously declared directly in the class or namespace to which the nested-name-specifier refers (i.e., neither inherited nor introduced by a using-declaration), and the class-specifier shall appear in a namespace enclosing the previous declaration.

An elaborated-type-specifier in an explicit instatiation containing a qualified-id is also not prohibited from appearing in the namespace nominated by its nested-name-specifier (13.9.3 [temp.explicit] paragraph 2):

An explicit instantiation shall appear in an enclosing namespace of its template. If the name declared in the explicit instantiation is an unqualified name, the explicit instantiation shall appear in the namespace where its template is declared.

(This asymmetry is due to the removal of inappropriate mention of classes in 9.3.4 [dcl.meaning] by issue 40 and a failure to insert the intended restrictions elsewhere.)

An example of this inconsistency is:

    namespace N {
      template <class T> struct S { };
      template <class T> void foo () { }

      template struct N::S<int>;   // OK
      template void N::foo<int>(); // ill-formed
    }

It is not clear that any purpose is served by the “outside of its namespace” restriction on declarators in definitions and explicit instantiations; if possible, it would be desirable to reconcile the treatment of declarators and class names by removing the restriction on declarators (which appears to be widespread implementation practice, anyway).

Rationale (April, 2006):

This is the same as issue 482.