我需要静态转换我的数字模板值吗
Do I need to static_cast my numeric template values?
我目前正在编写一个模板化的c++物理库。在我的函数中,我经常需要显式地比较或设置某些数值。我的目标是编写尽可能通用的库,因此我希望尽可能支持浮点和整数类型。
为了获得正确的类型,我经常在代码中使用对T
的显式强制转换。当然,在我的所有情况下,这都被解释为static_cast
。因此,我的问题是:我真的需要static_cast
这些值吗?或者我可能会因为做/不做而获得运行时开销?
示例:
我现在有这样的功能:
template <class T> auto is_elliptic(T eccentricity, T semi_major_axes = T(1)) {
return T(0) <= eccentricity < T(1) && T(0) < semi_major_axes;
}
然而,我也可以这样写:
template <class T> auto is_elliptic(T eccentricity, T semi_major_axes = T(1.0)) {
return T(0.0) <= eccentricity < T(1.0) && T(0.0) < semi_major_axes;
}
像这样:
template <class T> auto is_elliptic(T eccentricity, T semi_major_axes = 1) {
return 0 <= eccentricity < 1 && 0 < semi_major_axes;
}
或者像这样:
template <class T> auto is_elliptic(T eccentricity, T semi_major_axes = 1.0) {
return 0.0 <= eccentricity < 1.0 && 0.0 < semi_major_axes;
}
我不太关心这两个版本的可读性。我也不在乎这样一个事实,即在这里使用整数类型可能是无用的。我只想知道:
- 这些实现之间有区别吗
- 如果是,是什么
- 此外,对该代码编译器的可能优化是否依赖
编辑:
- 如果我想支持自定义数字类型,这些会改变吗
编辑:
正如评论中指出的那样,上面使用的链式比较实际上是错误的。代码应该类似于:
return T(0) <= eccentricity && eccentricity < T(1) && T(0) < semi_major_axes;
此外,可以使用constexpr
版本对代码进行运行时优化:
template <class T> constexpr auto is_elliptic(T eccentricity) {
return T(0) <= eccentricity && eccentricity < T(1);
}
template <class T> constexpr auto is_elliptic(T eccentricity, T semi_major_axes) {
return T(0) <= eccentricity && eccentricity < T(1) && T(0) < semi_major_axes;
}
取决于您想要什么。
此答案假定T
是int
或float
(尽管它适用于double
、long
或具有类似行为的自定义类型(,并且x
具有类型T
。
- 如果使用强制转换:
这很容易理解。但是,对于常量在类型T
中不可表示的情况,请小心。CCD_ 13与CCD_。
- 如果不使用强制转换:
[I]如果提升的操作数具有不同的类型,则应用额外的一组隐式转换,称为通常的算术转换,目的是生成通用类型[…]。
(来自https://en.cppreference.com/w/cpp/language/operator_arithmetic(
| T | Comparison | Equivalent to |
+-------+------------+---------------+
| int | 0<x | 0<x |
| int | 0.f<x | 0.f<(float)x | (*)
| float | 0<x | (float)0<x |
| float | 0.f<x | 0.f<x |
对于(*)
,比较是在float
上进行的,而强制转换常数(int(0.f<x)
(将在整数上进行比较。其他情况也是如此。
关于编译器开销:编译可能会稍微慢一些,但考虑到编译标准库头的速度已经有多慢,这应该无关紧要。
相关文章:
- 如何修复我的最大公约数代码?它适用于除零和零以外的所有数字
- 为什么当我输入较大的数字时,我的程序会到达文件末尾?
- 我的问题是关于C++中数字和序列的重复以及如何打印它们?
- 为什么当我输入一个被接受的数字时,我的 do-while 循环没有中断?
- 为什么我的程序在读取/写入文件时会删除最重要的数字?
- 为什么我的位移给出不正确的数字
- 为什么我的 while 循环永远不会在 C++ 中的数字猜测游戏中结束?
- 为什么当我在 c++ 中运行函数时,我的代码显示数字 53
- 我可以从具有不同数字分隔符的istream中读取双值吗
- 我需要静态转换我的数字模板值吗
- 我必须更改我的数字最后一个数字和第一个数字,但不要使用仅带有整数或循环的函数.例如从 12345 到 52341
- 如何让我的代码显示文件名不正确或文件中数字的平均值?
- 我的代码应该接受一个数字,并返回字母等级或"Grade is not valid"但 else 语句不起作用
- 为什么当我输入大量数字时,我的计算器程序开始闪烁和滚动
- 我的代码似乎在查找最大数字时存在语法错误
- 有效创建数字签名的正确方法是什么?我可以使用DSA_sign_setup()吗?
- 为什么我的C++程序输出不同的数字来将米转换为英尺?
- 为什么我的阶乘数查找器返回以C++输入的数字?(已编辑)
- 我可以在不指定数字分布的情况下使用随机生成器吗?
- 如何允许我的程序成功读取数字包含的文件