【问题标题】:Compiler discrepancy: Interaction between alias resolution and name lookup编译器差异:别名解析和名称查找之间的交互
【发布时间】:2016-07-12 07:09:48
【问题描述】:

考虑这段代码:

using type = long;

namespace n {
  using type = long;
}

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

这在Clang 3.7GCC 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 编译器

【问题讨论】:

    标签: c++ c++11 language-lawyer typedef name-lookup


    【解决方案1】:

    [namespace.udir]/6:

    如果名称查找在两个不同的命名空间中找到一个名称的声明,并且声明未声明相同的实体且未声明函数,则该名称的使用格式不正确。

    但是,它们确实声明了引用相同类型的名称,因此程序应该是格式良好的。这种解释是例如由core issue 1894的cmets确认:

      //[..]
    
      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;
      }
    

    【讨论】:

      【解决方案2】:

      7.3.4 / 6:

      如果名称查找在两个不同的名称中找到名称声明 命名空间,并且声明不声明相同的实体并且做 不声明函数,名称的使用格式不正确

      【讨论】:

      • @Columbo,我在看到你之前已经发布了我的答案。我会自己删除它,但我现在要离开它 - 对做它的人投反对票是错误的。