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

时间:2015-10-24 02:18:13

标签: 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吐出错误:

  

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

     

错误:对'X'的引用含糊不清

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

  

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

2 个答案:

答案 0 :(得分:3)

[namespace.udir] / 6:

  

如果名称查找找到两个不同的名称声明   名称空间,并且声明不会声明相同的实体   没有声明功能,名称的使用是不正确的。

对于X中的第一个X::X,将考虑命名空间和类。但是,名称空间的名称驻留在全局名称空间中,而类位于名称空间X中;因此,上述引用适用,因此Clang是正确的。 (当明确写出X时也会出现这种情况。)

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

  

对于名称空间X和名称m,名称空间限定的查找集    S(X,m)的定义如下:设    S 0 (X,m)mX的所有声明的集合,X的内联命名空间集合(7.3.1)。 如果 S 0 (X,m)是   非空, S(X,m) S 0 (X,m); 否则,[...]

此处,X是全局命名空间,m是&#34; X&#34;。很明显,我们找到了命名空间的声明,所以在这里查找是明确的。

答案 1 :(得分:1)

不是一个完整的答案,但这是一个明显的情况,甚至表明使用命名空间,对于与您需要声明命名空间的名称空间同名的对象。

"Function inside the namespace"
"Function inside the namespace"
"Function inside the class"

输出(GCC 4.9.2)

public static boolean dictHasWord(String str){
    for(int i = 0; i < dictionary.length; i++){
       if(str.equals(dictionary[i])){
           return true;
       }
    }
    return false;
}