c ++由于命名空间导致无法解释的类“尚未声明”错误

Posted

技术标签:

【中文标题】c ++由于命名空间导致无法解释的类“尚未声明”错误【英文标题】:c++ Unexplainable class “ has not been declared” error due to namespace 【发布时间】: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 ); 没有使用初始化程序定义静态数据成员。此处的初始化程序不能使用圆括号。 【参考方案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

【讨论】:

以上是关于c ++由于命名空间导致无法解释的类“尚未声明”错误的主要内容,如果未能解决你的问题,请参考以下文章

C++不使用匿名命名空间实现内部链接

深入理解命名空间

包含具有重复类的文件

由于命名空间[关闭]导致对象实例化错误

由于命名空间而无法反序列化 xml

如何把C++的源程序改写成C语言