3

comp.std.c++ Usenet の議論が非常に信頼できなくなったため、ここに再投稿します。私がそこに提出した最後のいくつかの投稿は無効になり、活動はほとんど停止しました. 私が禁止されているか、他の人が興味を失ったのではないかと思います。興味のあるすべての人がこの議論を見つけて、一般的な移行が行われることを願っています。たぶん、彼らは新しいモデレーターを任命するでしょう。


こんにちは!

条件演算子と xvalues に関するドラフト N3126 の私の現在の解釈では、次のアサーションが保持されると予想されます。

 int i = 0;
 int& j = true? i : i;
 int&& k = true? std::move(i) : std::move(i);   // #2
 assert(&i == &j); // Holds since C++98
 assert(&i == &k); // Should this hold as well?

5.16/4 言います:

[条件演算子への] 2 番目と 3 番目のオペランドが同じ値カテゴリの glvalue で、同じ型の場合、結果はその型と値カテゴリになります [...]

ただし、結果の glvalue が glvalue オペランドが参照するオブジェクトの 1 つを参照することを明確に述べているわけではありません。C++0x モードで GCC 4.5.1 を使用すると、2 番目のアサーションが失敗します。参照 k は、何らかの一時オブジェクトを参照しているようです。コロンの周りの両方のオペランドが同じタイプの xvalue である場合に、コミラーがそのような一時的なものを作成できるかどうかを誰かが明確にすることはできますか?

私は現在、GCC にバグがあるか、xvalue に関して最新ではないことを想定しています。

フォローアップの質問は、次のとおりです。式の値カテゴリを検出できたらいいと思いませんか? 条件演算子を無視すると、decltype を使用して式の値カテゴリを検出できます。しかし、何が

 bool xvalue = std::is_rvalue_reference<
   decltype( true ? std::move(i) : std::move(i) ) >::value;

譲るべきか?GCC 4.5.1 を使用すると、xvalue 変数は false で初期化されます。これは現在の標準草案に準拠していますか?

ティア、セバスチャン

4

1 に答える 1

2

GCC 4.5.1 は §5.16/4 に関して不適合だと思います。バグレポートを提出しましたか?

とにかく、その三項演算子コードに準拠していると思います。decltype§7.1.6.2/4 で定義されています。

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

  • e が括弧で囲まれていない id-expression またはクラス メンバー アクセス (5.2.5) である場合、decltype(e) は e によって名前が付けられたエンティティの型です。そのようなエンティティがない場合、または e がオーバーロードされた関数のセットを指定している場合、プログラムは不適切な形式です。
  • それ以外の場合、e が関数呼び出し (5.2.2) またはオーバーロードされた演算子の呼び出し (e を囲む括弧は無視されます) の場合、decltype(e) は静的に選択された関数の戻り値の型です。
  • それ以外の場合、e が左辺値の場合、decltype(e) は T& です。ここで、T は e の型です。
  • それ以外の場合、decltype(e) は e の型です。decltype 指定子のオペランドが未評価のオペランドです (条項 5)。

decltype適切な宣言を取得し、そこから目的の型を返すことで機能します。オーバーロードされていない演算子に関しては、ほとんどインテリジェンスがありません。たぶん別のポイント

  • それ以外の場合、eが xvalue の場合、decltype(e) は ですT&&。ここで、 はのT型ですe

特に、書かれているように、xvalues は prvalues として扱われます。さらに、式はstd::common_type(§20.7.6.6/3) の定義に正確に対応します。

簡単な回避策の 1 つ (造語: :vP ):

template< typename T1, typename T2 >
struct common_type_and_category {
    typedef typename std::conditional<
        std::is_same< T1, T2 >::value,
        T1,
        typename std::common_type< T1, T2 >::type
    >::type type;
};
于 2010-10-11T20:46:27.190 に答える