Template类,并强制某些方法由User实现

Template class and forcing certain methods to be implemented by User

本文关键字:方法 User 实现 Template      更新时间:2023-10-16

可能的重复:
是否可以编写C++模板来检查函数';的存在?

我正在尝试编写一个C++类模板。我想要的是,当这个类模板与用户定义类一起使用时,我想强制这些用户定义类实现某些方法,例如to_datafrom_data。我不希望那些用于基本C++基元数据类型。我该怎么做?例如,如果类的复制构造函数不可用,std::vector会给出编译错误。

您可以使必须由用户实现的方法成为纯虚拟函数。如果您不希望那些用于基本C++基元数据类型,您可以针对这些情况专门化您的模板,并为这些情况提供默认实现。

只需使用类模板中的方法:

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"

请注意,只有当我们尝试使用类模板的某些函数时,才会触发编译器错误。这是因为类模板的成员函数只有在使用它们时才会实例化(如果愿意的话,可以编译)。因此,只要不使用serializedeserialize成员函数,就可以用Bar实例化Serializer


关于第二个问题,即如何为基元类型提供不同的行为,您有几个解决方案。第一种方法是将类模板专门化为您想要以不同方式处理的类型。例如,下面的代码专门处理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