首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我需要static_cast我的数字模板值吗?

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

Stack Overflow用户
提问于 2018-07-26 09:18:42
回答 1查看 1.2K关注 0票数 0

我目前正在编写一个模板化的c++物理库。在我的函数中,我经常要显式地比较或设置某些数值。我的目标是编写尽可能通用的库,因此我希望尽可能支持浮点数和整数类型。

为了使类型正确,我经常在代码中使用显式强制转换为T。当然,在我的所有案例中,这都被解释为一个static_cast。因此,我的问题是:我真的需要static_cast这些值吗?或者我可以通过做/不做来获得运行时管理费用吗?

一个例子:

我现在有这样的功能:

代码语言:javascript
复制
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;
}

不过,我也可以这样写:

代码语言:javascript
复制
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;
}

如下所示:

代码语言:javascript
复制
template <class T> auto is_elliptic(T eccentricity, T semi_major_axes = 1) {
   return 0 <= eccentricity < 1 && 0 < semi_major_axes;
}

或者像这样:

代码语言:javascript
复制
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;
}

我不太关心这两种版本的可读性。我也不关心这个事实,在这里使用整数类型可能是无用的。我只想知道:

  • 这些实现之间有什么区别吗?
  • 如果是,那是什么?
  • 另外,在此代码编译器上可能的优化依赖于吗?

编辑:

  • 如果我想支持自定义的数字类型,这其中的任何一个会改变吗?

编辑:

正如注释中指出的那样,上面使用的链式比较实际上是错误的。代码应该类似于:

代码语言:javascript
复制
return T(0) <= eccentricity && eccentricity < T(1) && T(0) < semi_major_axes;

此外,可以使用constexpr版本对代码进行运行时优化:

代码语言:javascript
复制
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;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-07-26 09:39:40

取决于你想要什么。

这个答案假设Tintfloat (尽管它适用于具有类似行为的doublelong或自定义类型),x具有T类型。

  • 如果使用演员阵容:

这是非常简单的理解。但是,对于在T类型中不能表示常量的情况,请小心。0.5>x(int)0.5>x不一样。

  • 如果没有使用强制转换:

如果提升操作数有不同的类型,则应用附加的隐式转换集,称为通常的算术转换,目的是生成公共类型.

(来自arithmetic )

代码语言:javascript
复制
| 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))将对整数进行比较。对于其他情况,也是一样的。

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51535286

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档