шаблонная специализация для набора типов - PullRequest
4 голосов
/ 03 декабря 2010

У меня быстрый вопрос о том, как мне специализировать шаблон для набора типов данных. например,

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

Я хочу, чтобы это работало с int, long, double, float, поэтому я хочу специализировать его для этого набора типов данных. так что если пользователь попробует эту функцию с типом 'char', компилятор выдаст ошибку. если это дурак, дайте мне знать. спасибо

Ответы [ 5 ]

5 голосов
/ 03 декабря 2010

Это зависит от того, что вы хотите сделать. Если вы хотите, чтобы компилятор просто не смог найти подходящее разрешение для вызова функции, вы можете использовать ответ Флинша, который, вероятно, лучше, или вы можете использовать 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.

3 голосов
/ 03 декабря 2010

Поскольку релевантны только три типа данных long, double и float, и для них нет необходимости в дополнительной универсальной версии, просто отклоните template и предоставьте три функции для long, double и float.

2 голосов
/ 03 декабря 2010

Если вы хотите ограничить вашу функцию 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> {};

Надеюсь, это поможет вам. Теперь вы можете написать весь свой код в одной функции!

2 голосов
/ 03 декабря 2010

вы можете сделать это:

// 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 вызывается с типом, отличным от long, float или double.

0 голосов
/ 03 декабря 2010

Нет встроенного в язык способа указать, что шаблон может быть создан только с определенным набором параметров типа. Однако это не удастся скомпилировать для любого типа, для которого не определено operator /, что может быть достаточно для вас.

При разработке API рекомендуется избегать удивления вашего пользователя, и большинство пользователей будут удивлены, если вы скажете им, что им не позволено вычислять соотношение двух вещей, которые можно разделить!

Если вы действительно не хотите поведения по умолчанию, ответ Флинша является хорошим компромиссом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...