2010-12-03 202 views
4

我有一個關於如何專門化一組數據類型模板的快速問題。例如,一組類型的模板專門化

template<typename T> 
inline T getRatio(T numer, T denom){ 
    return (numer/denom); 
} 

我希望這與int,long,double,float一起工作,所以我想專門爲這組數據類型。所以如果用戶使用'char'類型來嘗試這個函數,編譯器會拋出錯誤。 如果這是一個讓我知道。 感謝

+0

所以,你希望它只能使用long,double,float和其他類型嗎? – EboMike 2010-12-03 19:14:31

+0

@EboMike。是的。 – blueskin 2010-12-03 19:15:08

回答

3

由於只有三種數據類型longdoublefloat是相關的,它們不需要額外的通用版本,只是拒絕templatelongdoublefloat提供三種功能。

+0

+1:只需使用超載。 – Puppy 2010-12-03 19:42:08

+0

這意味着三個功能,而不是一個維護。它可能只有三個和簡單的功能,但它讓我感到緊張,以後某些維護程序員將來只會改變其中的一些。 – KeithB 2010-12-03 20:08:01

+0

@KithithB - 你知道一個非模板函數可以調用模板函數,對吧? – 2010-12-03 20:12:54

-1

語言中沒有任何方法可以指定模板只能通過一組特定的類型參數來實例化。但是,對於沒有定義的operator /的任何類型,這將無法編譯,這對您可能已足夠。

在設計API時,避免讓用戶感到意外是一種很好的做法,如果您告訴他們不允許您計算兩種可以劃分的比例,大多數用戶會感到驚訝!

如果你真的不想要默認行爲,Flinsch的答案是一個很好的折衷。

2

,你可以這樣做:

// declaration 
template <typename T> inline T getRatio(T numer, T denom); 

// specialization for long  
template <> 
inline long getRatio<long>(long numer, long denom) { return (numer/denom); } 
// specialization for float 
template <> 
inline float getRatio<float>(float numer, float denom) { return (numer, denom); } 
// specialization for double 
template <> 
inline double getRatio<double>(double numer, double denom) { return (numer/denom); } 

這將導致鏈接錯誤,如果getRatio被稱爲比長,float或double以外的類型。

5

這取決於你想要做什麼。如果你希望編譯器根本無法找到該功能的適當的決議稱,你可以使用Flinsch的答案,這可能是最好的,也可以使用SFINAE:

template < typename T > is_an_ok_type : boost::mpl::false_ {}; 
template < > is_an_ok_type<int> : boost::mpl::true_ {}; 
... etc... 

template < typename T > 
typename boost::enable_if< is_an_ok_type<T>,T >::type 
get_ratio(T t1, T t2) 
{ 
    return t1/t2; 
} 

如果你需要某種合理可讀的錯誤而是使用靜態斷言; static_assert(C++ 0x)或BOOST_STATIC_ASSERT。

2

如果你想限制你的getRatio()函數僅適用於int, long, double and float,那麼你也可以使用這個函數。如果你使用char類型參數來調用它,它會產生「一個有意義的」編譯錯誤。編譯錯誤將爲:this_type_is_not_allowed_in_getRatio

//yourheader.h 
template<typename T> 
inline T getRatio(T numer, T denom) 
{ 
    typedef typelist<int, typelist<long, typelist<double, float>>> allowedtypes; 
    compile_time_checker<contains<allowedtypes, T>::result> this_type_is_not_allowed_in_getRatio; 
    return (numer/denom); 
} 

它使用此頭:

//metafunctions.h 
template<typename H, typename T> 
struct typelist 
{ 
    typedef H Head; 
    typedef T Tail; 
}; 

template<typename T, typename Tail> 
struct contains 
{ 
    static const bool result = false; 
}; 

template<typename Head, typename Tail, typename T> 
struct contains<typelist<Head, Tail>, T> 
{ 
    static const bool result = false || contains<Tail, T>::result; 
}; 

template<typename T, typename Tail> 
struct contains<typelist<T, Tail>, T> 
{ 
    static const bool result = true || contains<Tail, T>::result; 
}; 

template<bool b> struct compile_time_checker; 
template<> struct compile_time_checker<true> {}; 

希望,它可以幫助你。 現在只需一個函數即可編寫所有代碼!