【问题标题】:Why does list initialization allow conversion from double to float values?为什么列表初始化允许从双精度值转换为浮点值?
【发布时间】:2018-06-16 21:27:42
【问题描述】:

列表初始化({...} 语法)不允许缩小转换范围。例如,尝试使用3.14fint i 进行列表初始化会出现编译错误,因为从浮点值到整数的转换正在缩小:

<source>:11:32: error: narrowing conversion of '3.1400001e+0f' from 'float' to 'int' inside { } [-Wnarrowing]
     int i{3.14f};
                ^

话虽如此,为什么可以用3.14构造一个float f,它的类型是double? (从doublefloat 的转换被视为缩小范围。)执行以下操作:

float f{3.14};

没有编译错误。

【问题讨论】:

  • 您确定允许从 double 到 float 的转换吗? extern double y; struct X { float f; } x{y}; 我出错了。

标签: c++ c++11 list-initialization


【解决方案1】:

在被视为缩小转换的列表中,适合目标类型的常量表达式是一个例外。因此,虽然通常 double to float 正在缩小,但当您的 double 实际上是文字时,这是允许的。

http://coliru.stacked-crooked.com/a/6949f04fa4a8df17


从我手头的草稿(我认为接近 C++14):

8.5.4 列表初始化
(7.2) 窄化转换是隐式转换...
...从 long double 到 double 或 float,或从 double 到 float,除非源是常量 表达式和转换后的实际值在可以表示的数值范围内 (即使不能准确表示),

【讨论】:

  • 用 int 值初始化 char 时也一样。
  • @MárioFeroldi:它认为是一个常量表达式。 :) pi 但是,不是。
  • @MárioFeroldi 澄清了这个例子。
  • 哇,所以丢失精度允许的。 3.14 是无限二进制小数,所以(float) 3.14 != 3.14.
  • @ArneVogel:是的。您可以想象对于不适合其目的地的浮点值存在一种单独的转换错误 - 如果存在这样的事情,那么这个缩小转换规则简单地引用该规则可能是有意义的。然而,这条规则并不存在,而且实际上大多数开发人员并不真正关心他们的文字是否被准确表示。我相信这是规则例外的动机。
猜你喜欢
  • 2015-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-24
  • 2015-06-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多