使用{}初始化器在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,则警告将成为一个错误。
发布于 2013-11-02 01:19:29
缩小初始化列表中的数据类型会使您的c++11程序不正确,在这种情况下,编译器可以发出警告或继续运行。
有趣的是,您实际上可以将其更改为bool b = {1},而且没有任何警告,我假设这是因为bool的值在整数类型中保证转换为0和1。
这是确认错误的标准报价。
缩窄转换是隐式转换。 -从浮点数类型到整数类型,或 -从长双到双或浮动,或从双到浮动,除非源是一个常量表达式,转换后的实际值在可以表示的值范围内(即使不能准确表示),或 -从整数类型或非作用域枚举类型到浮点类型,除非源是常量表达式,转换后的实际值将符合目标类型,并在转换回原始类型时生成原始值,或 -从整数类型或非作用域枚举类型到不能表示原始类型所有值的整数类型,除非源是常量表达式,转换后的实际值将符合目标类型,并在转换回原始类型时生成原始值。 如前所述,在列表初始化中的顶级不允许进行此类转换。
发布于 2013-11-02 01:43:08
看上去:
bool b = {2} ;如果我们查看起草C++标准节8.5.4列表-初始化第7段,确实是一种缩小转换:
缩窄转换是隐式转换。
并包括以下要点(重点是地雷):
从整数类型或非作用域枚举类型到不能表示原始类型的所有值的整数类型,除非源是一个常量表达式,其积分提升后的值将适合目标类型。
bool不能表示值2,因此这是最严格意义上的收缩转换。这就说明了{}初始化的重点是防止隐式转换和增加类型安全性。您所指的旧风格所依赖的是:
bool b = 2这取决于4.12布尔转换节,该节指出:
..。零值、空指针值或空成员指针值转换为false;任何其他值都转换为真。..。
当然,{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 ]https://stackoverflow.com/questions/19737929
复制相似问题