我需要static_cast我的数字模板值吗?

时间:2018-07-26 09:18:43

标签: c++ templates type-conversion static-cast

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

1 个答案:

答案 0 :(得分:1)

取决于您的需求。


此答案假设Tintfloat(尽管它适用于doublelong或行为类似的自定义类型),并且x的类型为T

  • 如果使用演员表:

这很容易理解。但是,对于在类型T中无法表示常量的情况,请当心。 0.5>x(int)0.5>x不同。

  • 如果不使用演员表:
  

[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))将对整数进行比较。对于其他情况,则相同。

关于编译器的开销:编译的速度可能稍慢,但是考虑到标准库头的编译速度已经很慢了,应该无关紧要。