【问题标题】:c++ Unexplainable class “ has not been declared” error due to namespacec ++由于命名空间导致无法解释的类“尚未声明”错误
【发布时间】:2018-07-24 04:33:40
【问题描述】:

我有一些具有两个私有静态成员的模板类。 用户定义一个特征结构并将其提供给模板类,然后从它派生。

然后用户在 c++ 文件中定义静态成员,其中一个成员从另一个成员初始化。 出于某种原因,如果我没有完全指定 arg 的命名空间,我会收到“尚未声明类”错误。这只是我在嵌套命名空间中的问题,如果您在单个顶级命名空间中定义类型就没有问题,这让我认为这是一个编译器错误。 下面精简示例,使用 gcc 7.2 编译

template<typename Traits>
struct Base 
{
    static int x;
    static int y;
};

namespace foo::bar
{
    struct BarTraits
    {
    };

    using Bar = Base<BarTraits>;

    template<> int Bar::x = 0;
    template<> int Bar::y( Bar::x );  //error 
    //template<> int Bar::y( foo::bar::Bar::x ); //no error
}

【问题讨论】:

  • 谨防以预设您的问题无法回答的方式编写问题。如果您的错误确实无法解释,那么在这里询问它就没有多大意义了。
  • You should define them in the same namespace Base is defined in。或者直接从Traits模板参数中直接借用。
  • 其他编译器已经在x 给出了一个错误,说 cannot define or redeclare 'x' here because namespace 'bar' does not enclosure namespace 'Base<:bar::bartraits>'
  • 永远不要承认“让我认为这是一个编译器错误”。
  • template&lt;&gt; int Bar::y( Bar::x ); 没有使用初始化程序定义静态数据成员。此处的初始化程序不能使用圆括号。

标签: c++ gcc namespaces


【解决方案1】:

根据C++标准temp.expl.spec#3

可以在可以定义相应主模板的任何范围内声明显式特化。

您的代码违反了此声明,因为Bar::xBar::y 专门用于namespace foo::bar

由于已知缺陷https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56119,GCC 错误地接受了前两个专业化

以下固定代码

template<typename Traits>
struct Base  {
    static int x;
    static int y;
};

struct BarTraits {};
using Bar = Base<BarTraits>;

template<> int Bar::x = 0;
template<> int Bar::y( Bar::x );

被 GCC、Clang、MSVC 接受:https://gcc.godbolt.org/z/MPxjTzbah

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-31
    • 2016-11-05
    • 2012-01-29
    • 1970-01-01
    • 1970-01-01
    • 2019-09-26
    • 2018-03-30
    相关资源
    最近更新 更多