5

int()int{}はに等しい値の定数式であるため、0同等で交換可能であると考えたため、コンパイラはそれらを同等に扱わなければなりません。例えば、

 int a[0];      //error: zero-sized array not allowed in ISO C++
 int b[int()];  //error: zero-sized array not allowed in ISO C++
 int c[int{}];  //error: zero-sized array not allowed in ISO C++

ただし、交換できないコーナーケースがいくつかあるようです。

  • ポインターを初期化する場合:

    int *p = 0;     //ok
    int *q = int(); //error - by clang only
    int *r = int{}; //error - by gcc and clang both
    

    GCCおよびClangメッセージを参照してください。このコンテキストでは互換性があると思われるため、これは両方のコンパイラのバグであると思われますが、間違っていることが証明されれば幸いです。:-)

  • クラス テンプレートに渡す場合:

    template<int N> struct X{};
    
    X<0>      x1; //ok
    X<int{}>  x2; //ok (same as X<0>)
    X<int()>  x3; //error  
    

    GCCおよびClangメッセージを参照してください。

    のようなX<int()>同様の構文を以前に見た (そしておそらく使用した) ので、構文は非常によく 知られていstd::function<int()>ます。しかし、このコンテキストで言う仕様のセクションを知りたいのは、関数として扱われることであり、 which is always と同等ではありません。int()0intint()int{}0

4

1 に答える 1

5

int()とは両方とも、ゼロに評価される整数型の定数式の prvalue であるため、ゼロに評価される整数型の整数型の定数式 prvalue が必要なコンテキストではint{}、リテラルと交換可能です。0

どちらの式も、 5.19 定数式 [expr.const]で指定されている定数式の要件を満たしています。

に関してX<int()>、標準でint()は、 はこのコンテキストでは式として解釈されないと指定しています。

14.3 テンプレート引数 [temp.arg]

template-argumentでは、対応するtemplate-parameterの形式に関係なく、 type -idの間のあいまいさがtype-id に解決されます。

ポインター変換について:

4.10 ポインタ変換 [conv.ptr]

null ポインター定数は、整数型の整数定数式 (5.19) の prvalue であり、ゼロまたは type の prvalue に評価されますstd::nullptr_t

上記の段落に基づいて、 と の両方int()int{}null ポインター定数式です。これは、(非常にマイナーな) コンパイラのバグを示していますが、開いている欠陥レポート ( 903 ) があり、この段落の変更につながる可能性があります。

CWG の間では、現在指定されている任意のゼロ値定数式ではなく、リテラル 0 のみをヌル ポインター定数と見なすべきであるという強いコンセンサスがありました。

次の表現は、式の値を扱いますint()

8.5 初期化子 [dcl.init]

T 型のオブジェクトまたは参照をゼロで初期化するとは、次のことを意味します。

[該当しない省略条項]

T がスカラー型 (3.9) の場合、オブジェクトは値 0 (ゼロ) に設定され、整数定数式として取得され、T に変換されます。

[...]

タイプ T のオブジェクトを値で初期化するとは、次のことを意味します。

— T がユーザー提供のコンストラクター (12.1) を持つ (おそらく cv 修飾された) クラス型 (第 9 節) である場合、T のデフォルト コンストラクターが呼び出されます (T にアクセス可能なデフォルト コンストラクターがない場合、初期化の形式は正しくありません)。 );

[該当しない省略条項]

それ以外の場合、オブジェクトはゼロで初期化されます。

初期化子が括弧の空のセット、つまり () であるオブジェクトは、値で初期化されます。

の値については、次のようになりますint{}

8.5.4 リストの初期化 [dcl.init.list]

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

— 初期化子リストに要素がなく、T が既定のコンストラクターを持つクラス型の場合、オブジェクトは値で初期化されます。

[該当しない省略条項]

それ以外の場合、イニシャライザ リストに要素がない場合、オブジェクトは値で初期化されます。

C++ Working Draft Standard N3337 からのすべての引用。

于 2013-10-01T18:04:36.223 に答える