2012-10-03 38 views
1

Possible Duplicate:
Is it possible to write a C++ template to check for a function's existence?模板类,并迫使某些方法来通过用户

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

+0

是什么你声明了一些没有定义的虚拟方法(仅限签名)? (你也可以声明纯虚方法:“virtual void my_method(args)= 0;) – Neozaru

+0

@iammilind:我不认为这是重复的。事实上,这两个Q都是非常不相关的AFAICS。 –

+2

@Als它看起来像类似的,但是这个问题确实增加了不需要原始类型的方法的额外的扭曲 – CrazyCasta

回答

1

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

+0

所以我们必须为所有的原始类型提供专门化?听起来像很多工作 – juanchopanza

+0

这样做意味着类模板只能用于派生自公共基类(定义纯虚拟成员函数的类)的类型,这首先会(或多或少地)破坏使用模板的目的。 –

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" 

需要注意的是,当我们尝试使用类模板的一些功能的编译器错误时才会触发。这是因为类模板的成员函数在您使用它们时仅实例化(如果您愿意的话)。因此,只要您不使用成员函数和deserialize成员函数,就可以实例化SerializerBar


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