Date: Sun, 25 May 2025 21:40:50 +0300
[dcl.meaning.general]/3.4 of the current draft says:
Otherwise, the terminal name of the declarator-id is not looked up. If it
> is a qualified name, the declarator shall correspond to one or more
> declarations nominable in S; all the declarations shall have the same
> target scope and the target scope of the declarator is that scope.
> [Example 2:
> namespace Q {
> namespace V {
> void f();
> }
> void V::f() { /* ... */ } // OK
> void V::g() { /* ... */ } // error: g() is not yet a member of V
> namespace V {
> void g();
> }
> }
> namespace R {
> void Q::V::g() { /* ... */ } // error: R doesn't enclose Q
> }
> — end example]
Example 2 was moved here in C++23 with adoption of P1787 "Declarations and
where to find them". In C++20 it was in [namespace.memdef]/2 (which got
removed) saying:
Members of a named namespace can also be defined outside that namespace by
> explicit qualification ([namespace.qual]) of the name being defined,
> provided that the entity being defined was already declared in the
> namespace and the definition appears after the point of declaration in a
> namespace that encloses the declaration's namespace.
The second error in the example was explicitly explained by this
clause, but now [dcl.meaning.general]/3.4 doesn't explain it, and the
prohibition is actually due to [expr.prim.id.qual]/2:
A nested-name-specifier is declarative if it is part of
> - a class-head-name,
> - an enum-head-name,
> - a qualified-id that is the id-expression of a declarator-id, or
> - a declarative nested-name-specifier.
> A declarative nested-name-specifier shall not have a
> computed-type-specifier. A declaration that uses a declarative
> nested-name-specifier shall be a friend declaration or inhabit a scope that
> contains the entity being redeclared or specialized.
In particular, with the new terminology word "enclose" isn't even used with
namespaces in the wording, instead the notion of "contains" for scopes is
used, and P1787 has 'Disentangled “enclose” and “contain” definitions' as
one of its summary points (in history for r0 revision).
So, I think, either the explanation/comments of the example should be
updated, or the example should be divided and the relevant part moved to
[expr.prim.id.qual]/2. And, in either case, this would be classified as an
editorial issue, right?
-- Yuriy
Otherwise, the terminal name of the declarator-id is not looked up. If it
> is a qualified name, the declarator shall correspond to one or more
> declarations nominable in S; all the declarations shall have the same
> target scope and the target scope of the declarator is that scope.
> [Example 2:
> namespace Q {
> namespace V {
> void f();
> }
> void V::f() { /* ... */ } // OK
> void V::g() { /* ... */ } // error: g() is not yet a member of V
> namespace V {
> void g();
> }
> }
> namespace R {
> void Q::V::g() { /* ... */ } // error: R doesn't enclose Q
> }
> — end example]
Example 2 was moved here in C++23 with adoption of P1787 "Declarations and
where to find them". In C++20 it was in [namespace.memdef]/2 (which got
removed) saying:
Members of a named namespace can also be defined outside that namespace by
> explicit qualification ([namespace.qual]) of the name being defined,
> provided that the entity being defined was already declared in the
> namespace and the definition appears after the point of declaration in a
> namespace that encloses the declaration's namespace.
The second error in the example was explicitly explained by this
clause, but now [dcl.meaning.general]/3.4 doesn't explain it, and the
prohibition is actually due to [expr.prim.id.qual]/2:
A nested-name-specifier is declarative if it is part of
> - a class-head-name,
> - an enum-head-name,
> - a qualified-id that is the id-expression of a declarator-id, or
> - a declarative nested-name-specifier.
> A declarative nested-name-specifier shall not have a
> computed-type-specifier. A declaration that uses a declarative
> nested-name-specifier shall be a friend declaration or inhabit a scope that
> contains the entity being redeclared or specialized.
In particular, with the new terminology word "enclose" isn't even used with
namespaces in the wording, instead the notion of "contains" for scopes is
used, and P1787 has 'Disentangled “enclose” and “contain” definitions' as
one of its summary points (in history for r0 revision).
So, I think, either the explanation/comments of the example should be
updated, or the example should be divided and the relevant part moved to
[expr.prim.id.qual]/2. And, in either case, this would be classified as an
editorial issue, right?
-- Yuriy
Received on 2025-05-25 18:41:03