使用{}
中的C++11
初始值设定项初始化bool b = {2}
会产生以下警告消息:
warning: narrowing conversion of ‘2’ from ‘int’ to ‘bool’ inside { } [-Wnarrowing]
但是,使用旧样式bool b = 2
没有这样的问题。这背后的原因是什么?
更新:我使用g++ -std=c++11
编译了代码,它给了我警告。如果我添加选项-pedantic-errors
,警告就会出错。
答案 0 :(得分:8)
缩小初始化列表中的数据类型会使您的c ++ 11程序生成错误,在这种情况下,编译器可以发出警告或继续。
有趣的是,您实际上可以将其更改为bool b = {1}
并且没有警告,我假设因为bool的值保证在整数类型中转换为0和1。
这是确认错误的标准报价。
缩小转换是隐式转换 - 从浮点类型到整数类型,或
- 从long double到double或float,或从double到float,除非source是常量表达式,转换后的实际值在可以表示的值范围内(即使它不能精确表示),或者
- 从整数类型或无范围枚举类型到浮点类型,除非源是常量表达式,转换后的实际值将适合目标类型,并在转换回原始类型时生成原始值,或
- 从整数类型或未范围的枚举类型到不能表示原始类型的所有值的整数类型,除非源是常量表达式,并且转换后的实际值将适合目标类型并将生成原始值转换回原始类型时。
如上所述,列表初始化中的顶层不允许进行此类转换
答案 1 :(得分:4)
看起来像:
bool b = {2} ;
如果我们查看draft C++ standard部分8.5.4
列表初始化段 7 ,确实是缩小转化表示:
缩小转化是隐式转化
并包含以下项目符号(强调我的):
从整数类型或未范围的枚举类型到整数类型 除了之外,它不能代表原始类型的所有值 其中source是一个常量表达式,其值在积分之后 促销将适合目标类型。
bool
无法代表值2
,因此这是最严格意义上的缩小转化。这有意义{}
初始化的全部内容是prevent implicit conversions并增加类型安全性。您在此引用的旧样式依赖于:
bool b = 2
取决于4.12
布尔转换部分,其中包含:
[...]零值,空指针值或空成员指针值 转换为假;任何其他值都转换为true。 [...]
当然,{2}
将缩小转化的整个前提依赖于 true 和 false 的值的假设是1
和0
,据我所知,标准中无法保证。虽然标准承诺转换是唯一的隐含,但如果我们要使用文字,我们不需要依赖这个假设,我们有两个非常好的这个true
和false
的布尔文字是你应该使用的。
为了完整起见,此缩小转换 格式错误,它需要诊断,因此警告或错误是可以接受的。如果我们查看段落 3 ,它会说:
对象或类型T的引用的列表初始化定义为 如下:
并包含以下项目符号(强调我的):
否则,如果初始化列表具有E类型的单个元素且T不是引用类型或其引用类型与E引用相关,则从该元素初始化对象或引用; 如果需要缩小转化(见下文)将元素转换为T,则程序格式错误。
并包含以下示例:
[ Example:
int x1 {2}; // OK
int x2 {2.0}; // error: narrowing
—end example ]