名称空间与包含的类名称相同,对于gcc是ok,对于clang不好

vso*_*tco 5 c++ gcc clang language-lawyer c++11

考虑一下代码:

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() {}
Run Code Online (Sandbox Code Playgroud)

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

错误:'X'不是类,命名空间或枚举Foo f()

错误:对'X'的引用不明确

根据C++标准,代码在语法上是否有效?或者只是一个gcc bug?删除限定名称X::X并使用Foo<X>gcc choke也是如此

错误:模板参数1无效Foo f()

Col*_*mbo 3

[命名空间.udir]/6:

\n\n
\n

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

\n
\n\n

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

\n\n

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

\n\n
\n

对于命名空间X和 name m,命名空间限定的查找集\n S(X, m)定义如下:设\n S 0 (X, m)m是in的所有声明和(X的内联命名空间集)的集合。X7.3.1)。如果S 0 (X, m)不为空,则S(X, m)S 0 (X, m)否则,[\xe2\x80\xa6]

\n
\n\n

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

\n


归档时间:

查看次数:

864 次

最近记录:

9 年,10 月 前