C++数值类型之间的强制转换

C++ casting between numeric types

本文关键字:转换 之间 类型 C++      更新时间:2023-10-16

我知道C++中的不同转换运算符已经在这里讨论了很多次,但我的问题专门是关于数值类型之间的转换,而不是关于 C 样式和C++样式运算符之间的一般差异。我认为这是一个与在类层次结构中转换完全不同的主题。

假设我想将 int i 投到双精度,我有一些选择是

static_cast<double>(i)
(double) i
double(i)

就个人而言,在这种情况下,我更喜欢第 3 行中类似构造函数的样式,因为我喜欢表达这不是一个 castteen 类类型,我肯定会使用 static_castdynamic_cast .

除了在文本编辑器中搜索时难以找到这种类型的演员表之外,我选择的还有什么缺点吗?

static_cast<double>(i)无疑是您在这种特殊情况下意图的最清晰表达。

在数值类型之间进行转换时,通常距离未定义的行为仅一箭之遥。所以一般要小心。虽然你的强制转换是为每个可能的i值定义的,但将double强制转换为int可能会溢出int,并且该行为在C++中是未定义的。

我总是建议您检查目标类型是否可以容纳源类型。 std::numeric_limits<>::max()等可以在这里提供帮助。

C++标准没有指定 int 的最大大小(尽管 16、32 和 64 位 2 的补码很常见),因此,可能无法将其表示为double

在我的代码中,我有一个包含

  template<
        typename T/*the desired type*/,
        typename/*the source type*/ Y
    > T integral_cast(const Y& y)
    {
        static_assert(false, "undefined integral_cast");
    }

我专门为我需要的每个数字演员提供。

这些方法的一个主要缺点是强制转换对溢出和其他数字错误不安全。

使用 static_cast 是直接合理的解决方案,此方法不会被 PVS Studio 等静态代码分析工具标记。 (double)i方法会生成警告。

可能最安全的方法是拥有自己的演员阵容,比如说numeric_cast<T>()

template <class OT, class ST>
OT numeric_cast(const ST value)
{
    return static_cast<OT>(value);
}

此函数的优点是可以执行绑定检查和其他数字检查,以确保强制转换是合法的,并且不会返回(或获取)垃圾值。

还有另一种处理数字的方法,但它仅适用于常量的编译时值。对于此检查,用户定义的字符串文本