只需使用方法,你的类模板:
template <typename T>
struct Serializer
{
void serialize(T const & t) const { write(t.to_data()); }
void deserialize(T & t) const { t.from_data(read()); }
};
如果你实例化有相应的成员函数模板类型,一切都会好起来。如果他们不这样做,编译器会触发一个错误:
struct Foo
{
int val;
int to_data() const { return val; }
void from_data(int i) { val = i; }
};
struct Bar {};
Serializer<Foo> sf;
sf.serialize(); // OK
Serializer<Bar> sb;
sb.serialize(); // compiler error: Bar has no member function named "to_data"
需要注意的是,当我们尝试使用类模板的一些功能的编译器错误时才会触发。这是因为类模板的成员函数在您使用它们时仅实例化(如果您愿意的话)。因此,只要您不使用成员函数和deserialize
成员函数,就可以实例化Serializer
与Bar
。
关于第二个问题,即如何为基元类型提供不同的行为,您有几个解决方案。第一个是专门化你的类模板来处理你想要处理的类型。例如,下面的代码专门Serializer
,使其处理int
不同:
template <>
struct Serializer<int>
{
void serialize(int i) const { write(i); }
void deserialize(int & i) const { i = read();
};
然而,这意味着写一个专门为每个特定的类型,即使他们中的一些实际上以同样的方式处理。
一个不太麻烦的解决方案是使用类型特征和std::enable_if
取决于参数类型的一些特点选择正确的实现(在这种情况下,无论是原始与否):
#include <type_traits>
template <typename T, typename Enable = void>
struct Serializer
{
// same as before
};
// Partial specialization for fundamental types
template <typename T>
struct Serializer<T, typename
std::enable_if<std::is_fundamental<T>::value>::type>
{
void serialize(T t) const { write(t); }
void deserialize(T & t) const { t = read(); }
};
Serializer<Foo> sf; // first implementation
Serializer<int> si; // second (specialized) implementation
是什么你声明了一些没有定义的虚拟方法(仅限签名)? (你也可以声明纯虚方法:“virtual void my_method(args)= 0;) – Neozaru
@iammilind:我不认为这是重复的。事实上,这两个Q都是非常不相关的AFAICS。 –
@Als它看起来像类似的,但是这个问题确实增加了不需要原始类型的方法的额外的扭曲 – CrazyCasta