c++ - 命名空间与包含的类同名,gcc 可以,clang 不行

标签 c++ c++11 gcc clang language-lawyer

考虑代码:

template<typename T> 
class Foo{};

namespace X
{
    class X{};
}

using namespace X; // now both class X and namespace X are visible
Foo<X::X> f()
{
    return {};
}

int main() {}

gcc5.2 编译代码没有任何错误。然而 clang 吐出错误:

error: 'X' is not a class, namespace, or enumeration Foo f()

error: reference to 'X' is ambiguous

根据 C++ 标准,代码在语法上是否有效?或者只是一个 gcc 错误?删除限定名称 X::X并使用 Foo<X>相反也让 gcc 窒息

error: template argument 1 is invalid Foo f()

最佳答案

[命名空间.udir]/6:

If name lookup finds a declaration for a name in two different namespaces, and the declarations do not declare the same entity and do not declare functions, the use of the name is ill-formed.

对于 X::X 中的第一个 X,命名空间和类都会被考虑。但是,命名空间的名称驻留在全局命名空间中,而类驻留在命名空间 X 中;因此上面的引用适用,因此 Clang 是正确的。 (显然,当只写 X 时也会发生这种情况)。

::X 消除了这种歧义。查找不再进入命名空间。 [命名空间.qual]/2:

For a namespace X and name m, the namespace-qualified lookup set S(X, m) is defined as follows: Let S0(X, m) be the set of all declarations of m in X and the inline namespace set of X (7.3.1). If S0(X, m) is not empty, S(X, m) is S0(X, m); otherwise, […]

这里,X 是全局命名空间,m 是“X”。很明显,我们的命名空间的声明找到了,所以这里查找是确定的。

关于c++ - 命名空间与包含的类同名,gcc 可以,clang 不行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33313853/

相关文章:

c++ - Matrix Hell - 将 3D 纹理中的点转换为世界空间

c++ - 制作二维引擎 : compiling necessary libraries with the engine instead of the game

C++:如何将 memcpy 与指针 ** 一起使用?

c++ - c++ std::function 如何绑定(bind)到模板函数?

c++ - (++i)++ 是未定义的行为吗?

android - Android NDK 使用哪个编译器?

c++ - 如何将模板类限制为仅具有类型别名的特定专业

c - 使用带有 clang 的 c11 标准来使用 strcpy_s

c - 告诉 gcc 一个函数调用不会返回

c++ - 依赖注入(inject)和所有权问题