可能重复:
Is it possible to write a C++ template to check for a function's existence?
我正在尝试编写C ++类模板。我想要的是当这个类模板与用户定义的类一起使用时,我想强制这些用户定义的类实现某些方法,比如to_data
和from_data
。我不希望那些基本的C ++原始数据类型。我该怎么做呢?例如,如果类的复制构造函数不可用,则std::vector
会出现编译错误。
答案 0 :(得分:1)
您可以创建必须由用户纯虚函数实现的方法。如果您不希望那些基本的C ++原始数据类型,您可以针对这些情况专门化您的模板,并为这些情况提供默认实现。
答案 1 :(得分:1)
只需使用课程模板中的方法:
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"
请注意,只有在我们尝试使用类模板的某些函数时才会触发编译器错误。这是因为类模板的成员函数只在您使用它们时才被实例化(编译,如果您愿意)。因此,只要您不使用Serializer
和Bar
成员函数,就可以serialize
与deserialize
进行实例化。
关于第二个问题,即如何为基本类型提供不同的行为,您有几个解决方案。第一个是为您希望以不同方式处理的类型专门化您的类模板。例如,以下代码专门设置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