【问题标题】:Namespace having the same name as contained class, ok for gcc, not ok for clang命名空间与包含的类同名,gcc 可以,clang 不行
【发布时间】:2016-01-23 16:04:18
【问题描述】:

考虑代码:

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”不是类、命名空间或枚举 富 f()

错误:对“X”的引用不明确

根据 C++ 标准,代码在语法上是否有效?或者只是一个 gcc 错误?删除限定名称 X::X 并改用 Foo&lt;X&gt; 也会使 gcc 阻塞

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

【问题讨论】:

  • 我相信这里有答案:stackoverflow.com/questions/5856759/…
  • @Gread.And.Powerful.Oz 谢谢,但 2 个答案似乎相互矛盾。如果有人可以提供标准的报价,那就太好了。我的问题与我们都评论/回答的问题有关:stackoverflow.com/q/33313723/3093378
  • 还有一个:stackoverflow.com/questions/1539333/…,也许谷歌搜索会有所帮助:google.com/…
  • @Gread.And.Powerful.Oz 谢谢,我以前见过一些,但我想看看根据标准的答案是什么,因为一个非常流行的编译器认为它是正确,而另一个不正确。这些答案都没有给出任何明确的答案。另一方面,gcc 认为代码是正确的。这就是为什么我也标记了language-lawyer
  • 我刚才有个想法,你试过 Foo<::x::x> 吗? (注意前面的双冒号)

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


【解决方案1】:

[namespace.udir]/6:

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

对于X::X 中的第一个X,同时考虑命名空间和类。但是,名称空间的名称位于全局名称空间中,而类位于名称空间X 中;因此上述引用适用,因此 Clang 是正确的。 (这也发生在只是写X时,很清楚)。

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

对于命名空间 X 和名称 m,命名空间限定的查找集 S(X, m) 定义如下: 让 S0(X, m)X 中所有m 声明和X (7.3.1) 的内联命名空间集的集合。 如果 S0(X, m) 是 不为空,S(X, m)S0(X, m); 否则,[…] p>

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

【讨论】:

  • 谢谢。我想知道是否应该填写 gcc 错误,因为在这种情况下,标准并没有说“不需要诊断”。
  • @vsoftco 是的,请。虽然我认为我可能已经存在一个(但我宁愿提交它也不愿冒着根本不被报告的风险)
【解决方案2】:

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

#include <iostream>
#include <string>

namespace test
{
    void function1(void){std::cout << "Function inside the namespace" << std::endl;}

    class test
    {
    public:
        static void function1(void){std::cout << "Function inside the class" << std::endl;}    
    };
};

using namespace test;

int main()
{
    function1();

    test::function1();

    test::test::function1();
}

输出 (GCC 4.9.2)

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

【讨论】:

    猜你喜欢
    • 2020-10-03
    • 2010-11-21
    • 2016-10-23
    • 2011-03-21
    • 2011-07-14
    • 2016-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多