3
typedef decltype(true ? (long&&)0 : (long&&)0) T;

T はどうあるべきか?

gcc (4.7) によると、long. clang (トランク) によると、long&&. この違いにより、clang は gcc 4.7 の libstdc++ を使用するコードのコンパイルに失敗します。誰が正しいですか?

更新: ildjarnが指摘するように、Clang は正しく、Richard Smithが指摘するように、エラー libstdc++ は標準のエラーによるものです。関連する GCC バグ関連する欠陥レポートは次のとおりです。

4

1 に答える 1

5

クランは正しいです。N3337 §7.1.6.2/4:

によって示される型はdecltype(e)、次のように定義されます。

  • e括弧で囲まれていないid-expressionまたは括弧で囲まれていないクラス メンバー アクセスである場合decltype(e)は、 によって名前が付けられたエンティティの型ですe。そのようなエンティティがない場合、またはeオーバーロードされた関数のセットに名前が付けられている場合、プログラムは不適切な形式です。
  • それ以外の場合、がexvalue の場合は です。ここで、は のタイプですdecltype(e)T&&Te
  • それ以外の場合、がe左辺値の場合は です。ここで、は の型です。decltype(e)T&Te
  • それ以外の場合decltype(e)は、の型ですe

decltype指定子のオペランドが未評価のオペランドです。

§5/6:

[注: 次の場合、式は xvalue です。

  • 暗黙的または明示的に、戻り値の型がオブジェクト型への右辺値参照である関数を呼び出した結果、
  • オブジェクト型への右辺値参照へのキャスト
  • オブジェクト式が xvalue である非参照型の非静的データ メンバーを指定するクラス メンバー アクセス式、または
  • 最初のオペランドが xvalue で、2 番目のオペランドがデータ メンバーへの.*ポインターであるメンバーへのポインター式。

一般に、このルールの効果は、名前付きの右辺値参照が左辺値として扱われ、オブジェクトへの名前のない右辺値参照が xvalue として扱われることです。関数への右辺値参照は、名前が付けられているかどうかにかかわらず、左辺値として扱われます。—<em>終わりのメモ]

0リテラルは、このコンテキストでこれをオブジェクト型として修飾することを何らかの形で妨げる可能性があることを以前に警戒していましたが、§3.9/8 は物事を明確にしています:

オブジェクト型は、関数型でも、参照型でも、void 型でもない (おそらく cv 修飾された) 型です。

条件演算子はここでは何にも影響しません – §5.16/4:

2 番目と 3 番目のオペランドが同じ値カテゴリの glvalue で同じ型の場合、結果はその型と値カテゴリになり、2 番目または 3 番目のオペランドがビット フィールドの場合はビット フィールドになります。どちらもビットフィールドです。

この場合、両方とも同じ値カテゴリ (xvalue) であり、xvalue は glvalues です。

于 2012-04-28T01:29:37.460 に答える