我需要静态转换我的数字模板值吗

Do I need to static_cast my numeric template values?

本文关键字:数字 我的 静态 转换      更新时间:2023-10-16

我目前正在编写一个模板化的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;
}

取决于您想要什么。


此答案假定Tintfloat(尽管它适用于doublelong或具有类似行为的自定义类型(,并且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)(将在整数上进行比较。其他情况也是如此。

关于编译器开销:编译可能会稍微慢一些,但考虑到编译标准库头的速度已经有多慢,这应该无关紧要。

相关文章: