2010-12-03 155 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> {}; 

希望,它可以帮助你。 现在只需一个函数即可编写所有代码!