模板类并强制用户实现某些方法

时间:2012-10-03 06:31:22

标签: c++ stl

  

可能重复:
  Is it possible to write a C++ template to check for a function's existence?

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

2 个答案:

答案 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"

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


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