7

{}で初期化子を使用して初期C++11bool b = {2}すると、次の警告メッセージが表示されます。

warning: narrowing conversion of ‘2’ from ‘int’ to ‘bool’ inside { } [-Wnarrowing]

ただし、古いスタイルを使用する場合bool b = 2は、そのような問題はありません。この背後にある理由は何ですか?


更新: を使用してコードをコンパイルしたg++ -std=c++11ところ、警告が表示されました。オプションを追加する-pedantic-errorsと、警告がエラーになります。

4

2 に答える 2

4

次のようになります。

bool b = {2} ;

ドラフトC++標準セクションリスト初期化パラグラフ7を見ると、確かに縮小変換です:8.5.4

縮小変換は暗黙の変換です

次の箇条書きを含めます(強調鉱山):

整数型またはスコープのない列挙型から、元の型のすべての値を表すことができない整数型へ

boolは値を表すことができない2ため、これは厳密な意味での縮小変換です。{}初期化の全体的なポイントは、暗黙的な変換を防ぎ、型の安全性を高めることです。ここで参照している古いスタイルは、次のどれに依存していますか。

bool b = 2

4.12 これは、ブール変換のセクションに依存します。

[...] ゼロ値、ヌル ポインター値、またはヌル メンバー ポインター値は false に変換されます。その他の値は true に変換されます。[...]

もちろん、縮小変換{2}である前提全体は、 truefalseの値がandであるという仮定に依存しています。これは、私が知る限り、標準では保証されていません。変換で標準が約束しているのはこれだけですが、リテラル使用する場合、この仮定に頼る必要はありません。10truefalse

完全を期すために、この縮小変換ill-formedであり、診断が必要なため、警告またはエラーのいずれかが許容されます。パラグラフ3を見ると、次のように書かれています。

型 T のオブジェクトまたは参照のリスト初期化は、次のように定義されます。

次の箇条書きを含めます(強調鉱山):

それ以外の場合、初期化子リストに型 E の単一の要素があり、T が参照型ではないか、その参照型が E に関連する参照である場合、オブジェクトまたは参照はその要素から初期化されます。要素を T に変換するために縮小変換 (以下を参照) が必要な場合、プログラムは不正な形式です。

次の例が含まれます。

[ Example:
  int x1 {2}; // OK
  int x2 {2.0}; // error: narrowing
—end example ]
于 2013-11-02T01:43:08.330 に答える