19

12.8クラスオブジェクトのコピーと移動[class.copy]§31と§32は次のように述べています。

クラスreturn型を持つ関数のreturnステートメントで、式が関数return型と同じcv-unqualified型を持つ不揮発性自動オブジェクト(関数またはcatch-clauseパラメーター以外)の名前である場合、自動オブジェクトを関数の戻り値に直接構築することにより、コピー/移動操作を省略できます。

ソースオブジェクトが関数パラメーターであり、コピーされるオブジェクトが左辺値で指定されていることを除いて、コピー操作の省略基準が満たされている、または満たされる場合、コピーのコンストラクターを選択するためのオーバーロード解決は次のようになります。最初は、オブジェクトが右辺値で指定されているかのように実行されます。

したがって、次のように書くことができます。

unique_ptr<int> make_answer()
{
    unique_ptr<int> result(new int(42));
    return result;   // lvalue is implicitly treated as rvalue
}

ただし、g ++ 4.6.3は、名前ではない左辺値も受け入れることに気付きました。次に例を示します。

    return (result);
    return *&result;
    return true ? result : result;

対照的に、return rand() ? result : result;動作しません。コンパイラのオプティマイザが言語のセマンティクスに干渉していませんか?私が標準を解釈するとき、は名前ではなく括弧で囲まれた式であるreturn (result);ため、コンパイルしないでください。(result)私は正しいですか、それとも間違っていますか?

4

2 に答える 2

10

括弧で囲まれた表現について[√]

括弧で囲まれた式について話しているときは間違っており、返され、移動可能なオブジェクトの名前のみが含まれているときに移動をトリガーできないようにする必要があります。

5.1.1/1一般[expr.prim.general]

括弧で囲まれた式は、タイプと値が囲まれた式と同じである一次式です。括弧の存在は、式が左辺値であるかどうかには影響しません。括弧で囲まれた式は、囲まれた式を使用できる場合とまったく同じコンテキストで使用でき、特に明記されていない限り、同じ意味で使用できます。


constexpr条件演算子について[╳]

定数式と彼の条件付き演算子に関して標準を解釈する方法は、定数式であり、したがって結果を返すreturn true ? result : resultのと同等であるため、の使用は適切に動作するということです。

私は今、標準をより注意深く調べましたが、定数の条件式が「返された」式だけが書かれ​​た場合と同じであるとはどこにも言いません。

true ? <expr1> : <expr2>; // this is not the same as just writing <expr1>;

返品について*&result; [╳]

C99では、代わりに記述したのとまったく同じで*&resultあると明示的に述べられていますが、C++仕様ではそうではありません。result

*&result使用すると実際にと同じ左辺値が生成されること同意できますがresult、標準によれば*&result(もちろん)、「式は不揮発性自動オブジェクトの名前です」という式ではありません。

もちろん、には適切な名前が含まれていますが、それだけではありません。


要約すると...

return result; // #1, OK

return (result);                  // as described earlier, OK
return true ? result : result;    // as described earlier, ill-formed
return rand () ? result : result; // as described earlier, ill-formed
return *&result;                  // as described earlier, ill-formed
于 2012-07-16T18:20:28.340 に答える
1

括弧で囲まれた式は、特に明記されていない限り、括弧で囲まれていない式と同等です(たとえば、ADLルールで行われるように、または別の例ではdecltypeによって)。このように何かが同等である場合とそうでない場合は、注意が必要な場合があります(たとえば、ADLルールでは「括弧なし」は明示的に言及されていませんが、非終端記号の明示的な文法と、親がそうではないことを明確にする例が使用されています。同等と見なされます)。

その他の質問の場合:はい、GCCはASTに対していくつかの最適化を直接実行し、次のようなさまざまな無効なプログラムを受け入れます。

int a = 42;
int *p = 0 * a;
于 2012-07-17T20:46:55.163 に答える