c ++中的安全整数转换

时间:2010-06-24 15:56:42

标签: c++ templates

我想使用c ++模板创建一个简单的整数范围检查器和转换器 代码如下所示:

// D is the "destination" type and S the "source" type
template <class D, class S>
inline D SafeConvert( S value );

template <class S>
inline int SafeConvert<int>( S value ) {

    ASSERT( value >= S(INT_MIN) && value <= S(INT_MAX) );
    return int(value);
} /// error C2768: 'SafeConvert' : illegal use of explicit template arguments


template <class S>
inline size_t SafeConvert<size_t>( S value ) {

    ASSERT( value >= S(0) && value <= S(size_t(-1)) );
    return size_t(value);
} /// error C2768: 'SafeConvert' : illegal use of explicit template arguments


// ...

void test() {

    size_t v = INT_MAX+1;
    int iv = SafeConvert<int>(v);
}

但是我有以下编译错误:

error C2768: 'SafeConvert' : illegal use of explicit template arguments

我的问题是如何告诉编译器我只想专门研究D类?

感谢。

4 个答案:

答案 0 :(得分:5)

您不能部分专门化功能模板。您需要使用类包装器模仿它或使用标准函数重载。模仿的一个例子:

template <typename T1, typename T2>
struct processor;

template < typename T1, typename T2 >
T1 fun(T2 t2) { return processor<T1,T2>::apply(t2); }

template < typename T2 >
struct processor<int,T2>
{
   static int apply(T2 t2) { .... }
};

...etc...

答案 1 :(得分:4)

这将是一个麻烦,一个难以维持的地狱。

通常我建议使用numeric_limits

template <class D, class S>
D SafeConvert(S value)
{
  ASSERT(value >= std::numeric_limits<D>::min()
      && value <= std::numeric_limits<D>::max());
  return static_cast<D>(value);
}

然而,无论何时将有符号整数与无符号整数进行比较,编译器都会发出警告......(顺便说一句,从来没有真正理解这一点)

所以,我不会重新发明轮子,而是建议使用Boost.NumericConversion,特别是:boost::numeric_cast<>

当不需要检查时(即目标类型大于源类型),保证性能免费,否则执行必要的检查。

答案 2 :(得分:1)

编写SafeConverter<T, S>使用的结构SafeConvert。优于部分专业化将使用std::numeric_limits,甚至boost::numeric_cast,它已经以更复杂的方式实现了范围检查。

后者可以按如下方式实施:

template<typename T, typename S>
struct numeric_converter {
  static T convert(const S& val);
}
template<typename T, typename S>
T numeric_cast(const S& val) {
  typedef numeric_converter<T, S> converter;
  return converter::convert(val);
}

答案 3 :(得分:0)

我认为,只需编写SafeConvert<size_t, S>而不是SafeConvert<size_t>来专门设计第二个参数。诺亚罗伯茨在功能与类型的部分专业化方面也是正确的。