2012-10-03 47 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 
相關問題