Неоднозначный поиск имени с директивой использования

Не допускается помещать пространство имен и класс с одинаковым именем в одну декларативную область, т.е.

namespace A {}
class A{};

неверный формат (см. §3.3.1/4). Однако можно ввести имя любого из них с помощью директивы использования:

namespace N { namespace A {int i;} }

struct A {static int i;};

using namespace N;

int i = A::i; // The global struct, or namespace N::A?

Является ли этот код неправильно сформированным? VC++ так думает, а также Clang:

main.cpp:7:9: error: reference to 'A' is ambiguous
int i = A::i;
        ^
main.cpp:3:8: note: candidate found by name lookup is 'A'
struct A {static int i;};
       ^
main.cpp:1:25: note: candidate found by name lookup is 'N::A'
namespace N { namespace A {int i;} }
                        ^

Однако GCC принимает его.

Кто прав?


person Columbo    schedule 26.04.2015    source источник
comment
GCC выбирает N::A::i. Интересно, почему.   -  person Barry    schedule 27.04.2015
comment
@Barry Я так же сбит с толку, так как ожидал, что он предпочтет более поверхностное объявление, то есть ближе к точке поиска.   -  person Columbo    schedule 27.04.2015


Ответы (1)


Код неправильно сформирован. При поиске A §7.3.4/6 выполняет следующие шаги:

Если поиск имени находит объявление имени в двух разных пространствах имен, и объявления не объявляют одну и ту же сущность и не объявляют функции, использование имени является неправильным.

Здесь пространствами имен являются глобальное пространство имен и N, а объектами являются пространство имен N::A и класс ::A.

person Columbo    schedule 26.04.2015