为什么这段代码会给出错误,"template specialization requires 'template<>'"?
Why does this code give the error, "template specialization requires 'template<>'"?
当我尝试用Clang编译这个
template<class T>
struct Field
{
char const *name;
Field(char const *name) : name(name) { }
};
template<class Derived>
class CRTP { static Field<Derived> const _field; };
class Class : public CRTP<Class> { };
Field<Class> const CRTP<Class>::_field("blah");
int main() { }
我error: template specialization requires 'template<>'
Field<Class> const CRTP<Class>::_field("blah");
~~~~~~~~~~~ ^
我完全不明白这个错误。我对_field
的定义有什么问题,我如何修复它?
(注意_field
的参数不一定对所有子类都相同)
为了让编译器将其识别为模板专门化(例如能够检查语法),您需要template
关键字:
template<>
Field<Class> const CRTP<Class>::_field("blah");
它的括号是空的,因为所有模板参数都是特化的,但是你不能把它放在一边。
该错误准确地说明了缺少的内容。template<>
在该行之前缺失。
template<>
Field<Class> const CRTP<Class>::_field("blah");
但是,请注意,如果Field<Class>
的类型唯一,则可以使用给定字符串构造Field<Class>
的所有实例。template<typename T>
struct field_trait;
template<class T>
struct Field
{
char const *name;
Field() : name(field_trait<T>::get_name()) {}
};
template<class Derived>
class CRTP { static Field<Derived> const _field; };
template<class Derived>
class CRTP<Derived>::_field;
class Class;
template<>
struct field_traits<Class> {
static const char* get_name() { return "blah"; }
};
class Class : public CRTP<Class> { };
int main() { }
这意味着Field<Class>
的每个实例总是以"blah"
命名。
我的一个问题是,你真的需要存储说Field<Class>
实际上有一个指向字符串的指针,如果是这样,它需要是唯一的,如果是这样,它需要是"裸"吗?因为找出static
实例存在的位置有点烦人。
与field_traits
一起:
template<class Derived>
class CRTP { static Field<Derived>& field() const { static Field<Derived> _field( field_traits<Derived>::get_name()); return _field; };
这将"_field
存储在哪里"的问题移动到编译器的问题。并由field_traits<T>::get_name()
的内容初始化
静态数据成员必须同时具有声明和定义。如果这是一个普通类,它看起来像这样:
// header:
class C {
static int i;
};
// source:
int C::i = 3;
模板通常不在源文件中定义,所以代码看起来像这样:
// header:
template <class T>
class C {
static int i;
};
template <class T>
int C<T>::i = 3;
在您的代码中,您没有静态数据成员的定义。你不用也没关系。但是编译器抱怨的代码为CRTP<Class>
定义了一个静态数据成员;这是一个专门化(因为它并不适用于CRTP
的所有实例化,只适用于这个实例化),编译器说你必须告诉它这是一个专门化。照我说的做:
template <>
Field<Class> const CRTP<Class>::_field("blah");
或者,编写非专门化模板版本,使用通常的模板语法:
template <class T>
Field<T> const CRTP<T>::_field("blah");
相关文章:
- 表示"accepting anything for this template argument" C++概念的通配符
- 传递给std::function template的template参数究竟代表什么
- EASTL矢量<向量<int>>连续的
- 在template中使用std::variant的template函数
- C++ template for QList
- C++ - 为什么这里需要'template'关键字?
- 使用"std::enable_if_t" "function template has already been defined"
- C++模板错误:"invalid explicitly-specified argument for template parameter"
- C++ class template
- 在"template"和函数声明之间使用:template<typename trait> using tr = base_trait<trait> void fn(tr::t
- 为什么编译器说"candidate template ignored: couldn't infer template argument 'InputIterator'"?
- 为什么在这种情况下我需要 .template
- std::span constructor, libcxx vs libstdc++, template vs non-
- 模板函数参数到模板函数的"candidate template ignored: could not match ..."
- MacOS 上的 LLVM - 标准文件 iosfwd 中未知类型名称'template'
- std::get like (partial) template specialization
- 实现多类型算术运算符时如何解决"template argument deduction/substitution failure"
- 更新 Visual Studio 2017,现在出现编译错误 C7510:"回调":使用依赖模板名称必须以 'template' 为前缀
- C++ 中的"template <typename From, typename Tag> struct Alias;"是什么?
- Template类定义中的Template方法与声明不匹配