只需使用方法,你的類模板:
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
成員函數,就可以實例化Serializer
與Bar
。
關於第二個問題,即如何爲基元類型提供不同的行爲,您有幾個解決方案。第一個是專門化你的類模板來處理你想要處理的類型。例如,下面的代碼專門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
是什麼你聲明瞭一些沒有定義的虛擬方法(僅限簽名)? (你也可以聲明純虛方法:「virtual void my_method(args)= 0;) – Neozaru
@iammilind:我不認爲這是重複的。事實上,這兩個Q都是非常不相關的AFAICS。 –
@Als它看起來像類似的,但是這個問題確實增加了不需要原始類型的方法的額外的扭曲 – CrazyCasta