Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template specialization for a set of types

Tags:

c++

templates

How do I specialize a template for a set of data types? For example:

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

I want to specialize it for a set of data types so it only works with int, long, double and float. So if the user would try to use this function with a char type, the compiler would throw error.

like image 916
Chenna V Avatar asked Dec 28 '22 04:12

Chenna V


2 Answers

It depends on what you want to do. If you want the compiler to simply fail to find an appropriate resolution for the function call you could use Flinsch's answer, which is probably best, or you can use 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;
}

If you want some sort of reasonably readable error instead you use a static assert; either static_assert (C++0x) or BOOST_STATIC_ASSERT.

like image 108
Edward Strange Avatar answered Jan 07 '23 22:01

Edward Strange


you might do this:

// 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); }

this will result in a linker error if getRatio is called with a type other than long, float or double.

like image 34
Drako Avatar answered Jan 07 '23 20:01

Drako