为什么在从 double 转换为 float 时大括号初始化不会抛出缩小错误?

Why doesn't braced initialization throw a narrowing error when converting from double to float?

每个 C++ 教程都在前面提到的两件事:

  1. 大括号初始化通常在可能的情况下更优越,因为它会在缩小转换期间抛出错误,例如
int narrow{1.7}; // error: narrowing conversion of '1.7e+0' from 'double' to 'int'
  1. 您必须将浮点数显式声明为浮点文字,否则它们将默认为双精度文字
float some_float{1.7f};

然而,在 Windows 上使用 g++ 编译器时,我发现了一些奇怪的东西 -

float narrow{1.7}; // still a float despite no f postfix
double not_narrow{1.7}; // actually a double

此代码编译没有任何错误,并且 sizeof(narrow) returns 4,其中 sizeof(not_narrow) returns 8,如预期的那样。
将鼠标悬停在 1.7 上,VSCode 将其识别为双重文字 ~=1.699999999999999956,但 float 随后将其缩小为 ~=1.700000048。
我认为这可能只是因为 1.7 作为浮点数和双精度数都有效,所以我尝试了

float narrow{1.699999999999999956};

但这会产生相同的结果。
为什么大括号初始化不会在此处抛出错误(警告、诊断消息等)以将双字面值缩小为浮点数?这是 g++ 特有的,还是 C++ 的一般怪癖?我很想更好地理解。

如果“源是常量表达式并且转换后的实际值在可以表示的值范围内(即使不能准确表示)”(C++20 [dcl.init.list]/7.2)。

如果您考虑一下,double{1.7}float{1.7} 很可能都不准确。但如果你写的是后者,就可以合理地假设你是认真的,禁止这样做也没什么好处。