[英]Why does `bool b = 2` work well but `bool b = {2}` yield a warning of narrowing conversion?
使用C++11
的{}
初始化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
,則警告將成為錯誤。
縮小初始化列表中的數據類型會使您的c ++ 11程序生成錯誤,在這種情況下,編譯器可以發出警告或繼續執行。
有趣的是,你實際上可以將它改為bool b = {1}
並且沒有警告,我假設因為bool的值保證在整數類型中轉換為0和1。
這是確認錯誤的標准報價。
縮小轉換是隱式轉換
- 從浮點類型到整數類型,或
- 從long double到double或float,或從double到float,除非source是常量表達式,轉換后的實際值在可以表示的值范圍內(即使它不能精確表示),或者
- 從整數類型或無范圍枚舉類型到浮點類型,除非源是常量表達式,轉換后的實際值將適合目標類型,並在轉換回原始類型時生成原始值,要么
- 從整數類型或未范圍的枚舉類型到不能表示原始類型的所有值的整數類型,除非源是常量表達式,並且轉換后的實際值將適合目標類型並將生成原始值轉換回原始類型時。
如上所述,列表初始化中的頂級不允許進行此類轉換
看起來像:
bool b = {2} ;
如果我們看一下C ++標准草案第8.5.4
節,那么確實是一個縮小的轉換。 列表初始化第7段說:
縮小轉換是隱式轉換
並包括以下子彈( 強調我的 ):
從整數類型或未范圍的枚舉類型到不能表示原始類型的所有值的整數類型 ,除非源是一個常量表達式,其整數提升后的值將適合目標類型。
bool
不能代表值2
所以這是最嚴格意義上的縮小轉換。 這有意義{}
初始化的重點是防止隱式轉換並增加類型安全性 。 你在這里提到的舊款式依賴於:
bool b = 2
這取決於4.12
布爾轉換部分,其中說:
[...]零值,空指針值或空成員指針值轉換為false; 任何其他值都轉換為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 ]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.