简体   繁体   English

C ++中的安全整数转换

[英]safe integer conversion in c++

I want to create a simple integer range checker and converter using c++ templates. 我想使用c ++模板创建一个简单的整数范围检查器和转换器。
The code looks like this: 代码如下:

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

However I have the following come compilation errors: 但是我有以下编译错误:

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

My question is how to tell the compiler that I want to specialize only the D class ? 我的问题是如何告诉编译器我只想专门研究D类?

Thanks. 谢谢。

You can't partially specialize function templates. 您不能部分专门化功能模板。 You need to mimic it with a class wrapper or use standard function overloading. 您需要使用类包装器来模仿它,或者使用标准函数重载。 An example of mimicing: 模仿的示例:

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...

It's going to be a bother, and a hell to maintain. 这将是一个麻烦,要维护一个地狱。

Normally I would advise using the numeric_limits : 通常我建议使用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);
}

However there is a warning emitted by the compiler whenever you compare a signed integer with an unsigned one... (never really understood this by the way) 但是,每当您将有符号整数与无符号整数进行比较时,编译器都会发出警告……(顺便说一句,请不要真正理解这一点)

So, instead of reinventing the wheel, I shall advise the use of Boost.NumericConversion and notably: boost::numeric_cast<> . 因此,我将建议您使用Boost.NumericConversion ,而不是重新发明轮子,尤其是: boost::numeric_cast<>

It's guaranteed to be performance free when the check is not required (ie the destination type is bigger than the source type) and otherwise perform the necessary checks. 当不需要检查时(即目标类型大于源类型),并确保执行其他必要的检查,则可以保证它不影响性能。

Write a structure SafeConverter<T, S> that is used by SafeConvert . 编写一个由SafeConvert使用的结构SafeConverter<T, S> Better than partial specialization would be using std::numeric_limits , or even boost::numeric_cast , which already implements range checking in a more sophisticated way. 比部分专业化更好的方法是使用std::numeric_limits ,甚至使用boost::numeric_cast ,它已经以更复杂的方式实现了范围检查。

The latter could be implemented as follows: 后者可以如下实现:

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

Just write SafeConvert<size_t, S> instead of SafeConvert<size_t> , I think, to specialise only the second parameter. 我想只写SafeConvert<size_t, S>而不是SafeConvert<size_t>来仅专门化第二个参数。 Noah Roberts is correct, too, on the point of partial specialisation of functions versus types. 在功能与类型的部分专业化方面,诺亚·罗伯茨(Noah Roberts)也是正确的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM