我有以下代码:
class A
{
public:
A(const unsigned int val) : value(val) {}
unsigned int value;
};
int main()
{
int val = 42;
A a(val);
A b{val}; // <--- Warning in GCC, error in Microsoft Visual Studio 2015
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么仅在列表初始化使用的情况下才会出现缩小转换警告?
我以为括号初始化不允许缩小。但是为什么int const允许char括号初始化?
int value1 = 12;
char c1{value1}; // error! no narrowing
const int value2 = 12;
char c2{value2}; // why is this fine?
Run Code Online (Sandbox Code Playgroud)
在Godbolt上看到它。
每个 C++ 教程早期都会提到两件事:
int narrow{1.7}; // error: narrowing conversion of '1.7e+0' from 'double' to 'int'
Run Code Online (Sandbox Code Playgroud)
float some_float{1.7f};
Run Code Online (Sandbox Code Playgroud)
然而,当在 Windows 上使用 g++ 编译器时,我发现了一些奇怪的事情 -
float narrow{1.7}; // still a float despite no f postfix
double not_narrow{1.7}; // actually a double
Run Code Online (Sandbox Code Playgroud)
此代码编译时没有任何错误,并sizeof(narrow)返回 4,其中sizeof(not_narrow)返回 8,正如预期的那样。
将鼠标悬停在 1.7 上时,VSCode 将其识别为双精度文字 ~=1.699999999999999956,但 float 随后将其缩小到 ~=1.700000048。
我认为这可能只是 1.7 作为浮点数和双精度数都有效,所以我尝试了
float narrow{1.699999999999999956};
Run Code Online (Sandbox Code Playgroud)
但这会产生相同的结果。
为什么花括号初始化不会在这里抛出错误(警告,诊断消息,任何东西)来将双精度文字缩小为浮点数?这是 g++ 特有的,还是 C++ 的一般怪癖?我很想更好地理解。