Несоответствие компилятора: взаимодействие между разрешением псевдонима и поиском имени

Рассмотрим этот код:

using type = long;

namespace n {
  using type = long;
}

using namespace n;
int main() {
  type t;
}

Это правильно компилируется на Clang 3.7 и GCC 5.3, но MSVC 19* выдает следующее сообщение об ошибке:

main.cpp(9): error C2872: 'type': ambiguous symbol
main.cpp(1): note: could be 'long type'
main.cpp(4): note: or       'n::type'

Является ли этот код правильно сформированным? В какой части стандарта указывается, разрешается ли псевдоним перед проверкой неоднозначности?


Обратите внимание, что Clang и GCC выдают аналогичные ошибки MSVC, если вы измените один из этих псевдонимов.

Я полностью осознаю, как уточнение имени разрешит двусмысленность, мне просто интересно, что стандарт говорит об этом.


*- Просто вставьте код и запустите его по этой ссылке, я не знаю, есть ли онлайн-компилятор MSVC с постоянными ссылками.


person TartanLlama    schedule 24.03.2016    source источник


Ответы (2)


[namespace.udir]/6:

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

Однако они объявляют, что имя относится к одному и тому же типу, поэтому программа должна быть правильно сформирована. Эта интерпретация, например. подтверждается комментариями в основном выпуске 1894:

  //[..]

  namespace C {
    // The typedef does not redefine the name S in this
    // scope, so issue 407's resolution does not apply.
    typedef A::S S;
    using A::S;
    // **The name lookup here isn't ambiguous, because it only finds one
    // entity**, but it finds both a typedef-name and a non-typedef-name referring
    // to that entity, so the standard doesn't appear to say whether this is valid.
    struct S s;
  }
person Columbo    schedule 24.03.2016

7.3.4 / 6:

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

person SergeyA    schedule 24.03.2016
comment
@Columbo, я опубликовал свой ответ до того, как увидел твой. Я бы удалил это сам, но я оставлю это сейчас - голосование против того, кто это сделал, было неправильным. - person SergeyA; 24.03.2016