我对要部分专用于多种类型的成员函数所需的语法感到不满。这是我所拥有的:
#include <cstdint>
#include <string>
class Property
{
public:
virtual int read(uint8_t *) = 0;
};
template<typename T>
class PropertyValue
{
T value_;
public:
int read(uint8_t *);
};
// specialized for std::string
template<>
int PropertyValue<std::string>::read(uint8_t *buf) { /* put string-value to buf */}
现在,我想专门针对不同枚举类型的读取功能。我尝试了enable_if
和is_same
的组合,这些组合看起来令人反感,然后将其放入模板声明中(编译器告诉我现在有2个模板参数,而预期是1个)。
将其放入类定义中也不起作用。在外面...好,这就是我目前拥有的。
// specialize for some enums
template<typename T>
typename std::enable_if<std::is_same<T, enum Enum1>::value ||
std::is_same<T, enum Enum2>::value, int>::type
PropertyValue<T>::read(uint8_t *buf)
{
return encode_enum(buf, value_);
}
我的想法哪里错了?
编辑:像这样编写并编译并起作用:
template<>
int PropertyValue<Enum 1>::read(uint8_t *buf)
{
return encode_enum(buf, value_);
}
template<>
int PropertyValue<Enum 2>::read(uint8_t *buf)
{
return encode_enum(buf, value_);
}
答案 0 :(得分:3)
PropertyValue::value
本身不是模板。它不是模板类,也不是模板函数。它是模板类的成员,与模板本身不同。
您必须专门研究整个课程。
template<>
class PropertyValue<std::string>
{
std::string value_;
public:
int read(uint8_t *)
{
// Your specialization goes here.
}
};
即使read()
本身是模板,也必须专门化其类,然后才能专门化模板类的模板成员。
当然,如果您的模板类具有许多其他成员和方法,则每个成员和方法都必须在此处进行专门化,从而导致大量代码被重复。届时,您将面临几种重构重复代码的选择。最好的方法取决于特定的细节。
但这就是完成的方式...
编辑:一种常见的方法是使用帮助程序模板类:
template<typename T> class PropertyValue; // Forward declaration
template<typename T> class do_read {
public:
static int do_it( PropertyValue<T> &me, uint8_t *p )
{
// your default implementation
}
};
template<> class do_read<std::string> {
public:
static int do_it( PropertyValue<std::string> &me, uint8_t *p )
{
// your specialization
}
};
template<typename T>
class PropertyValue
{
T value_;
public:
int read(uint8_t *p)
{
return do_read<T>::do_it(*this, p);
}
};