如何在模板中定义浮点常量.避免在运行时强制转换
How to define floating point constants within template. Avoid casts at run-time
假设我有一个简单的函数可以做这样的事情:
template<typename T>
T get_half(T a){
return 0.5*a;
}
该函数通常将在T为双或浮点的情况下进行评估。标准规定0.5将是一个双精度(0.5f表示浮动)。如何编写上面的代码,使0.5始终是T类型,以便在评估产品或退货时没有强制转换?我希望0.5在编译时是一个T类型的常数。这个问题的重点是,我希望避免在运行时进行转换。
例如,如果我写:
template<typename T>
T get_half(T a){
return T(0.5)*a;
}
我能绝对确定T(0.5)是在编译时评估的吗?如果没有,实现这一目标的正确方法是什么?如果需要的话,我可以使用c++11。
提前谢谢。
在c++11中,我有一个numeric_traits类,如下所示(在头文件中)
template<typename Scalar>
struct numeric_traits{
static constexpr Scalar one_half = 0.5;
//Many other useful constants ....
};
所以在我的代码中,我会使用这个作为:
template<typename T>
T get_half(T a){
return numeric_traits<T>::one_half*a;
}
这就是我想要的,即0.5在编译时以我需要的精度解析,并且在运行时不会发生强制转换。然而,缺点是:
- 每次需要新常量时,我都需要修改numeric_traits
- sintax可能太烦人了?(当然,这不是什么大问题)
- 最好是有这样的东西:常量(0.5),它在运行时解析为T类型
再次提前感谢您。
没有也不可能有任何方法强制在运行时永远不计算常量,因为有些机器根本没有一条指令可以加载一种类型的所有可能值。例如,机器可能只有16位加载常量指令,其中0x12345678
需要在运行时计算为0x1234 << 16 | 0x5678
。或者,这样一个常数可以从内存中加载,但这可能是一个比计算它更昂贵的操作
你需要稍微相信你的编译器。在可行的系统上,任何具有任何优化量的编译器都将以翻译0.5f
的方式翻译T(0.5)
,假设T
是float
。0.5f
将以对您的平台最合理的方式进行计算。这可能涉及将其加载为常量,也可能涉及计算它。或者谁知道呢,如果得到相同的结果,编译器可能会将T(0.5)*a
更改为a/2
。
在您的问题中,您将给出一个添加numeric_traits
辅助类的示例。国际海事组织认为,这太过分了。在constexpr
产生影响的极不可能的情况下,您可以只写
template <typename T>
T get_half(T a) {
constexpr T half = 0.5;
return half * a;
}
然而,在我看来,这仍然弊大于利:您的get_half
现在不能再与非文字类型一起使用。它需要类型来支持常量表达式中double
的转换。假设您有一个任意精度的rational
类型,编写时没有考虑constexpr
。现在不能使用get_half
,因为初始化constexpr T half = 0.5;
无效,即使0.5 * a
可能已经编译。
即使使用numeric_traits
帮助程序类,情况也是如此;它并不是因为我把它移到了函数体中而无效。
- 是否可以在运行时强制转换模板参数?
- 在 c++ 中将集合转换为向量和向量转换为字符串时出现运行时异常
- Antlr cpp 运行时 任何错误的指针转换?
- 如何在运行时将指向派生类的 void* 正确转换为指向基类的 void*
- 积分转换的运行时检查
- 使用向量将给定表达式转换为波兰表示法时出现运行时错误
- 动态强制转换的运行时检查
- 将 constexpr 结构转换为运行时结构
- 薄板样条形状转换运行时错误 [使用代码 -1073741819 退出]
- 寻求与类型为 std::invalid_argument 的未捕获异常相关的运行时错误的建议: stoi:无转换
- 在运行时根据某些元数据强制转换参数包值
- 常规强制转换不会引发运行时错误
- 如果没有运行时错误,我无法从MYSQL_ROW转换为System::String类型
- 如何在模板中定义浮点常量.避免在运行时强制转换
- 在运行时加载 .so 的 C++ 静态强制转换
- 将 void* 强制转换为仅在运行时已知的几种类型
- C++基于运行时类型实现强制转换
- 在运行时强制转换为派生类型
- 如何将这个运行时高效的函数转换为constexpr
- char数组在运行时转换为String