模板定义的非模板错误
Template definition of non-template error
我想在多线程环境中结合使用CRTP模式和一些锁定机制来实现访问同步。
我的代码是这样的:
//-- CRTP base class with some sync/lock mechanism
template<typename T, typename SYNC>
struct Base {
static std::unordered_map<int, std::string> s_map;
static SYNC s_sync;
};
//-- derived class using CRTP
template<typename SYNC>
struct ProductX : public Base<ProductX<SYNC>, SYNC> {};
//-- static initialisation
template<typename SYNC>
std::unordered_map<int, std::string> Base<ProductX<SYNC>, SYNC>::s_map {
{ 1, "value_1" },
{ 2, "value_2" }
}
但是我得到
编译时错误:模板定义非模板
std::unordered_map<int, std::basic_string<char> > Base<ProductX<SYNC>, SYNC>::s_map
。
静态s_map
初始化引发错误。谁能指出我哪里做错了吗?
您使用Base<ProductX<SYNC>, SYNC>
作为s_map
定义中的成员专门化,因此您实际上需要Base
的相应部分专门化(§14.5.5.3/1)。换句话说,试图定义一个不存在的部分专门化的成员。
尝试提供专门化:
template<typename SYNC>
struct ProductX;
//-- CRTP base class with some sync/lock mechanism
template<typename T, typename SYNC>
struct Base {};
template<typename SYNC>
struct Base<ProductX<SYNC>, SYNC> {
static std::unordered_map<int, std::string> s_map;
static SYNC s_sync;
};
//-- derived class using CRTP
template<typename SYNC>
struct ProductX : public Base<ProductX<SYNC>, SYNC> {};
//-- static initialisation
template<typename SYNC>
std::unordered_map<int, std::string> Base<ProductX<SYNC>, SYNC>::s_map {
{ 1, "value_1" },
{ 2, "value_2" }
};
。
一个简化的例子。
template <class A, class B>
struct C
{
static int x;
};
template <class A, class B> int C<A, B>::x = 0; // this works
然而template <class A> int C<A, double>::x = 0; // same error as yours
后一个定义属于不存在的C的部分专门化。创建一个:
template <class A>
struct C<A, double>
{
static int x;
};
template <class A> int C<A, double>::x = 1;
一切都好。
c++允许:
template<typename SYNC>
std::unordered_map<int, std::string> Base<ProductX<SYNC>, SYNC>::s_map { };
只能使用相应的部分模板类特化。要做到这一点,请查看下面哥伦布和n.m.用户的回应。然而,缺点是您必须为您以这种方式创建的每个ProductX
类重新定义所有内容。Ie。在我的情况下,如果我想创建类ProductX
, ProductY
, ProductZ
,我将不得不为它们中的每一个定义部分专门化,包括所有成员函数等,这不是很实用IMHO。
如果我们不想编写整个类的特化,我们必须使用带有无规范模板定义的静态变量:
template<typename T, typename SYNC>
std::unordered_map<int, std::string> Base<T, SYNC>::s_map { };
或完全专门化的模板定义:
struct NoSync { };
template<typename NoSync>
std::unordered_map<int, std::string> Base<ProductX<NoSync>, NoSync>::s_map { };
下面是完整模板专门化的完整示例:
//-- CRTP base class with some sync/lock mechanism
template<typename T, typename SYNC>
struct Base {
static std::unordered_map<int, std::string> s_map;
static SYNC s_sync;
static std::string& value_name1(int value) { return s_map[value]; }
};
//-- derived class using CRTP
template<typename SYNC>
struct ProductX : public Base<ProductX<SYNC>, SYNC> {};
struct NoSync {};
//-- static initialisation
template<>
std::unordered_map<int, std::string> Base<ProductX<NoSync>, NoSync>::s_map {
{ 1, "value_1" },
{ 2, "value_2" }
};
int main() {
ProductX<NoSync> p;
std::cout << "Value: " << p.s_map[1] << "n";
std::cout << "Value: " << p.value_name1(2) << "n";
}
这个可以很好地编译。
我要感谢哥伦布和n.m。感谢他们的回答,并为我指出了正确的方向!我会选择你的答案,但我想在不编写类模板专门化的情况下展示这个解决方案。
相关文章:
- 如何修复此错误:未定义对"距离(浮点数,浮点数,浮点数,浮点数,浮点数)"的引用
- 我的项目不会像"undefined reference to `grpc::g_core_codegen_interface'"那样使用未定义的引用错误进行编译
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- 使用命名空间时出现多个定义错误
- C++错误C2600:无法定义编译器生成的特殊成员函数(必须首先在类中声明)
- 对C宏的未定义引用,但在定义它时会出现重新定义错误
- 编写代码时C++出现错误:错误 1 错误 C2601:'circle':本地函数定义是非法的
- 在运算符重载定义中使用成员函数(const错误)
- 尝试调用 .h 文件中定义的变量时出现变量未定义错误
- 在C++中使用内联方法时出现未定义的符号错误
- 已定义函数时出现 G++ "未定义的引用"错误
- C++ G++ 编译器 - 错误:隐式声明的定义
- 链接 cmake 时出现未定义的引用错误
- 在头文件和 cpp 文件中使用一次 #pragma 时出现结构重定义错误
- 错误:未定义对'oboe::AudioStreamBuilder::openStream(oboe::AudioStream**)'的引用
- 链接阶段出现多重定义错误
- 已经以性格错误定义了
- vim ctag导致了对乐趣的错误定义
- C++ 隐式声明的编译器错误定义
- 编译器错误-定义问题.C++