![](/img/trans.png)
[英]How to specialize a templated member-function into a templated class in C++?
[英]How to specialize a non-templated-member function of a template class for multiple types?
我正在咬指甲部分专门针对多种类型的成员函数所需的语法。 这是我有的:
#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 */}
现在我想专门针对不同的枚举类型使用read-function。 我尝试了一下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_);
}
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);
}
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.