提问人:ByteMe95 提问时间:2/14/2018 最后编辑:François AndrieuxByteMe95 更新时间:11/27/2021 访问量:790
由于命名空间,c++ 无法解释的类“尚未声明”错误
c++ Unexplainable class “ has not been declared” error due to namespace
问:
我有一些模板类有两个私有静态成员。 用户定义一个特征结构并将其提供给模板类,然后模板类从中派生。
然后在 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
}
答:
0赞
Fedor
11/27/2021
#1
根据 C++ 标准 temp.expl.spec#3
可以在可以定义相应主模板的任何范围内声明显式专业化。
您的代码违反了此声明,因为 和 专门用于 .Bar::x
Bar::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
评论
Base
的同一命名空间中定义它们。或者直接从模板参数中借用它们。Traits
x
template<> int Bar::y( Bar::x );
不定义具有初始值设定项的静态数据成员。此处不能对初始值设定项使用圆括号。