Consider following code snippet with C++20 using-enum-declaration:
namespace A { enum A {}; };
using namespace A;
using enum A;
gcc-trunk rejects it with:
<source>:4:12: error: reference to 'A' is ambiguous
4 | using enum A;
| ^
<source>:1:20: note: candidates are: 'enum A::A'
1 | namespace A { enum A {}; };
| ^
<source>:1:11: note: 'namespace A { }'
1 | namespace A { enum A {}; };
| ^
<source>:4:12: error: 'A' has not been declared
4 | using enum A;
| ^
However, msvc accepts it. Interestingly, if I add a namespace qualifier for enum A
:
namespace A { enum A {}; };
using namespace A;
using enum A::A;
gcc accepts it this time, but msvc rejects it with:
<source>(4): error C2872: 'A': ambiguous symbol
<source>(1): note: could be 'A'
<source>(1): note: or 'A::A'
Which compiler is right?
gcc is wrong here (submitted 100'084).
The grammar for
using enum A;
is from [enum.udecl]:Lookup for such a thing is defined in [basic.lookup.elab]:
An elaborated-enum-specifier is one kind of elaborated-type-specifier, so we do type-only lookup. Which is defined as, in [basic.lookup.general]/4:
This means that when we look up
A
, while we find both theenum A
and thenamespace A
, because our lookup is type-only we only consider the former and not the latter. As a result, we only have a single candidate and that's the one our lookup finds. There is no ambiguity.