【问题标题】:Ambiguity accessing identifier in global and nested anonymous namespaces全局和嵌套匿名命名空间中的歧义访问标识符
【发布时间】:2021-12-28 03:23:01
【问题描述】:

以下代码:

namespace { constexpr int x = 1; }
namespace X { namespace { constexpr int x = 2; } }
using namespace X;

int main() {
  static_assert( ::x == 1 );
}

在 MSVC 中成功编译,它更喜欢第一个匿名命名空间来查找 ::x 而不是 X::(anonymous namespace)

但是,由于选择不明确,GCC 和 Clang 都拒绝了该代码。演示:https://gcc.godbolt.org/z/zPEGzGar3

哪个编译器在这里?

【问题讨论】:

    标签: c++ namespaces language-lawyer


    【解决方案1】:

    unnamed namespaces的这个参考中有一个类似的例子:

    namespace {
        int i; // defines ::(unique)::i
    }
    void f() {
        i++;   // increments ::(unique)::i
    }
     
    namespace A {
        namespace {
            int i;        // A::(unique)::i
            int j;        // A::(unique)::j
        }
        void g() { i++; } // A::(unique)::i++
    }
     
    using namespace A; // introduces all names from A into global namespace
    void h() {
        i++;    // error: ::(unique)::i and ::A::(unique)::i are both in scope
        A::i++; // ok, increments ::A::(unique)::i
        j++;    // ok, increments ::A::(unique)::j
    }
    

    据此,由于GCC和Clang选择不明确而拒绝代码应该是正确的。

    命名空间提供了一种防止大型名称冲突的方法 项目。

    在命名空间块内声明的符号被放置在命名范围内 这可以防止它们被误认为是同名符号 在其他范围内。

    正如该解释所述,引入namespace 是为了避免或解决名称冲突。恕我直言,这些代码示例显然是在试图制造名称冲突。

    【讨论】:

    • 示例可能是“不同”:限定名称查找与非限定名称查找。
    • 请注意,qualified_lookup 还考虑了using namespace
    • @Jarod42 qualified_lookup 也考虑了using namespace «also» 是什么意思?那不合格的不行吗?
    • @LanguageLawyer:人们可能会认为using namespace 仅适用于不合格(这是我在检查之前的第一个想法,特别是因为我在一些标准库实现)。所以 "also" 用于 "as unqualified lookup"
    猜你喜欢
    • 1970-01-01
    • 2020-07-10
    • 1970-01-01
    • 2021-04-19
    • 2012-05-11
    • 2015-01-08
    • 2015-11-04
    • 2017-08-26
    • 2018-02-03
    相关资源
    最近更新 更多