c ++因命名空间而无法解释的类"尚未声明"错误

Byt*_*e95 5 c++ gcc namespaces

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

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

Fed*_*dor 0

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

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

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

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

以下固定代码

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

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