假定我正在使用返回foo
的函数double
,但是我正在程序中使用float
(例如,许多计算机图形应用程序中的惯例)。
我不必为foo
改写float
,因为我不在很多地方使用,而且空间(以及可能还有速度)的开销不足以证明这样做的合理性。将foo
设为可处理多种类型的函数模板也不是一种选择,因为该函数来自库。
我有多种选择来应对这种情况:
1)按原样使用该功能
float f = foo();
这会给编译器警告“可能丢失数据”,我想消除它,因为我确定在这种特殊情况下精度损失不是问题。
2)显式转换为float:
float f = static_cast<float>(foo());
消除了警告,并向读者表明我正在转换为浮动在此处,但是使迅速掌握发生的情况变得更加困难,尤其是当行变长或需要强制转换多个参数时。
3)编写一个包装,将转换隐藏为浮动
float foo_float() { return static_cast<float>foo(); }
float f = foo_float();
没有警告,比(2)更易于阅读,但可能导致许多功能/ lambda并没有真正添加新功能。
我想知道:
请注意,当我确定函数的结果适合我使用的较小类型时,整数类型可能会出现相同的问题。
答案 0 :(得分:2)
您问:
Are there more ways to deal with this situation?
是的,例如,处理溢出问题-boost具有名为Numeric Conversion的库,该库可以公开并帮助处理这种情况。 (尤其是 numeric_cast
)
Am I missing pitfalls in one of the three approaches?
溢出。另外,在代码中留下这种已知的警告通常也是不可接受的。
概述
Boost数字转换库是用于 描述和执行不同数值之间的转换 类型。
该库为以下子集提供了一种特殊的替代方法 std :: numeric_limits <>,bounds <> traits类,它提供了一个 获取a范围的边界值的一致方法 数字类型。
它还包括一组特征类,它们描述了 从源到目标的转换的编译时属性 数字类型。算术和用户定义的数值类型都可以是 使用。
基于政策的转换器对象,该对象使用conversion_traits进行选择 提供了优化的实现。这样的实现使用 适用于源/目标的最佳范围检查代码 组合。
The converter's out-of-range behavior can be customized via an OverflowHandler policy. For floating-point to integral conversions, the rounding mode can be selected via the Float2IntRounder policy. A custom low-level conversion routine (for UDTs for instance) can be passed via a RawConverter policy. The optimized automatic range-checking logic can be overridden via a UserRangeChecker policy.