Visual C++ 2017 和 gcc 5.4 在此代码片段中为Line B
但不为Line A
生成conversion from 'const unsigned char' to 'const float' requires a narrowing conversion
警告:
#include <iostream>
int main() {
const unsigned char p = 13;
const float q = p; // Line A
std::cout << q << 'n';
const unsigned char c[3] = {0, 1, 255};
const float f[3] = {c[2], c[0], c[1]}; // Line B
for (auto x:f)
std::cout << x << 'n';
}
此警告是否有效?为什么Line B
与Line A
区别对待?
警告有效,从 C++11 开始,在聚合初始化中禁止缩小范围转换;但在复制初始化中不应用(和以前一样)。
如果初始值设定项子句是表达式,则允许根据复制初始化
, except if they are narrowing (as in list-initialization) (since C++11).
进行隐式转换在 C++11 之前,聚合初始化允许缩小转换范围,但不再允许。
和
列表初始化通过以下方式限制允许的隐式转换 禁止以下行为:
- 从整数类型转换为浮点类型,除非源是可以存储其值的常量表达式 完全在目标类型中
顺便说一句:c[0]
、c[1]
和c[2]
不是常量表达式;你可以将数组声明为constexpr
,即constexpr unsigned char c[3] = {0, 1, 255};
.然后应用异常,B 行也可以正常工作。