Reputation: 311038
I would like to check myself whether I understand correctly the following quote below from the C++ 20 Standard (English is not my native language).
Section 9.7.1 Namespace definition:
2 In a named-namespace-definition, the identifier is the name of the namespace. If the identifier, when looked up (6.4.1), refers to a namespace-name (but not a namespace-alias) that was introduced in the namespace in which the named-namespace-definition appears or that was introduced in a member of the inline namespace set of that namespace, the namespace-definition extends the previously-declared namespace. Otherwise, the identifier is introduced as a namespace-name into the declarative region in which the named-namespacedefinition appears.
That is may a namespace be defined in a namespace and then extended in one of its inline namespace? Or vice versa. May a namespace be defined in an inline namespace and then be extended in its enclosing namespace?
Here is a demonstrative program.
#include <iostream>
inline namespace N1
{
inline namespace N2
{
namespace N3
{
void f( int ) { std::cout << "f( int )\n"; }
}
}
namespace N3
{
void f( char ) { std::cout << "f( char )\n"; }
}
}
int main()
{
N3::f( 10 );
N3::f( 'A' );
}
The program output is
f( int )
f( char )
However for this program the compiler issues an error saying that reference to 'N3' is ambiguous.
#include <iostream>
inline namespace N1
{
namespace N3
{
void f( int ) { std::cout << "f( int )\n"; }
}
inline namespace N2
{
namespace N3
{
void f( char ) { std::cout << "f( char )\n"; }
}
}
}
int main()
{
N3::f( 10 );
N3::f( 'A' );
}
Upvotes: 2
Views: 258
Reputation: 119239
may a namespace be defined in a namespace and then extended in one of its inline namespace?
No. In your second example, when the compiler sees the definition of N3
inside N2
, the lookup of N3
finds the N3
that was declared outside N2
, but that N3
was not "introduced in the namespace in which the named-namespace-definition appears" (since it's not inside N2
), or "introduced in a member of the inline namespace set of that namespace" since the inline namespace set of N2
is the set of transitively inline namespaces inside N2
. Thus, this new definition of N3
doesn't extend the previous one.
May a namespace be defined in an inline namespace and then be extended in its enclosing namespace?
Yes. In your first example, N3
when looked up finds N2::N3
which was "introduced in a member of the inline namespace set" since N2
is part of the inline namespace set of N1
.
We can understand the rationale for this apparent asymmetry as follows: in the second example, when N3
is initially defined, it's being defined as a member of N1
and not a member of any inline namespace of N1
. Later, when N2::N3
is being defined, if it were to extend N1::N3
, it would be retroactively making N3
a member of N2
, which goes against common sense and is therefore disallowed. In the first example, N3
is initially defined as a member of the inline namespace N2
and there is no issue with extending it with the second definition later. (Though I cannot see an obvious reason why this is useful.)
Upvotes: 2
Reputation: 23701
I'll try to rewrite the standard wording in a less dense (but possibly less precise) way:
We are lexically inside namespace X
.
We encounter something that looks like namespace Y { ... }
.
We look up Y
. If Y
is not a namespace name, move on1.
Was Y
introduced (directly) in X
? If so, move to point 6.
Was Y
introduced in a namespace that is part of the inline set2 of namespaces of X
? If yes, move to 6. If not, move on1.
Y
does extend the namespace we found in step 3.
1 "Move on" in the sense of "ignore the cited standard paragraph".
2 The inline namespace set of N is the transitive closure of all inline namespaces in N.
may a namespace be defined in a namespace and then extended in one of its inline namespace?
No. We only consider the directly enclosing namespace (N3
is extended in N1
in your first example, and in N2
in your second one) and its inline namespaces. This is why your second example does not work: N2
(or its inline set of namespaces) does not contain any previous definition of N3
.
May a namespace be defined in an inline namespace and then be extended in its enclosing namespace?
Yes.
The examples you show are consistent with the standard wording.
Upvotes: 2