使用boost :: numeric_cast <>

ana*_*lyg 14 c++ boost type-conversion

当我想在不同的整数类型之间进行转换时,似乎最好的语法是使用boost::numeric_cast<>():

int y = 99999;
short x = boost::numeric_cast<short>(y); // will throw an exception if y is too large
Run Code Online (Sandbox Code Playgroud)

我从来没用过那个; 但是语法非常简单,所以一切都很顺利.

现在假设我想做一些更高级的事情:我希望它能够返回目标类型的最小值或最大值(饱和度),而不是抛出异常.我无法想出一种表达方式,但文档表明它是可能的(可能使用RawConverter策略).所有我能想到的是以下丑陋:

short x = numeric_cast<short>(max(min(y, SHORT_MAX), SHORT_MIN);
Run Code Online (Sandbox Code Playgroud)

那么我怎么能用boost来表达"饱和的演员" numeric_cast呢?

sth*_*sth 15

你可能会做这样的事情:

#include <limits>

template<typename Target, typename Source>
Target saturation_cast(Source src) {
   try {
      return boost::numeric_cast<Target>(src);
   }
   catch (const boost::negative_overflow &e) {
      return std::numeric_limits<Target>::lowest();
      /* Or, before C++11:
      if (std::numeric_limits<Target>::is_integer)
         return std::numeric_limits<Target>::min();
      else
         return -std::numeric_limits<Target>::max();
      */
   }
   catch (const boost::positive_overflow &e) {
      return std::numeric_limits<Target>::max();
   }
}
Run Code Online (Sandbox Code Playgroud)

(对于支持它的类型,错误情况也可以返回-inf/+ inf).

通过这种方式,您可以让Boost numeric_cast确定该值是否超出范围,然后可以做出相应的反应.

  • @sth,OP显然想要一个永远不会抛出异常的解决方案(但是会使值饱和).如果我们有选择使得内部实现有或没有异常,那么在没有必要时(出于上述原因)避免它们似乎更好 - 这就是全部:). (4认同)
  • @Kos:如果项目没有使用所有语言功能,那就是该项目的问题.没有人应该为不使用某些功能的语言编写代码,因为其他人可能不喜欢该功能. (3认同)
  • @Kos:假设提升`numeric_cast`处理有符号/无符号(我当然希望它有),这仍然可以正确处理它.如果你不想使用任何异常,你可能不应该首先使用`numeric_cast`,因为该函数的整点似乎是**会抛出错误. (3认同)