20

const へのローカル左辺値参照と右辺値参照は、一時変数の有効期間を延長できます。

const std::string& a = std::string("hello");
std::string&& b = std::string("world");

初期化子が単純な式ではなく、条件演算子を使用している場合にも機能しますか?

std::string&& c = condition ? std::string("hello") : std::string("world");

結果の 1 つが一時オブジェクトで、もう 1 つがそうでない場合はどうなるでしょうか。

std::string d = "hello";
const std::string& e = condition ? d : std::string("world");

C++ は、条件が false の場合に一時的な有効期間を延長することを義務付けていますか?

コピー不可能なオブジェクトに関するこの質問に答えているときに、質問が出てきました。

4

2 に答える 2

5

それらの両方は問題ありません。

§5.16 は述べています (非常に要約されています):

2 2 番目または 3 番目のオペランドの型が void の場合

いいえ。

3 その他、第 2 オペランドと第 3 オペランドの型が異なる場合

いいえ。

4 2 番目と 3 番目のオペランドが同じ値カテゴリの glvalue の場合

いいえ。(最初は両方とも prvalue で、2 番目は glvalue で、もう 1 つは prvalue です。)

5 それ以外の場合、結果は prvalue です

さて、これらは両方とも prvalues になります。バインディングは問題ありませんが、バインディングは何ですか?

6 左辺値から右辺値 (4.1)、配列からポインタ (4.2)、および関数からポインタ (4.3) への標準変換は、2 番目と 3 番目のオペランドで実行されます。

よし、どちらもまだ右辺値になっていない場合は、現在は右辺値です。

6 (続き) これらの変換の後、次のいずれかが成立します。

2 番目と 3 番目のオペランドは同じ型です。結果はそのタイプです。オペランドがクラス型の場合、結果は、最初のオペランドの値に応じて、2 番目のオペランドまたは 3 番目のオペランドのいずれかからコピー初期化される、結果の型の一時的な prvalue です。

わかりましたので、それはどちらかですstd::string(first_operand)またはstd::string(second_operand).

とにかく、条件式の結果は新しい prvalue 一時的であり、参照にバインドすることによって拡張されるのはその値です。

于 2013-01-18T19:26:46.440 に答える
3
std::string d = "hello";
const std::string& e = condition ? d : std::string("world");

条件がfalseの場合、C ++は一時の有効期間を延長することを義務付けていますか?

そうなる。条件は右辺値式であり、const参照にバインドされると、コンパイラーは名前のないオブジェクトを作成し、そのオブジェクトに参照をバインドします。私が100%確信していないのは、寿命が延長された一時的なものなのstd::string("world")か、それともそのコピーが(概念的に)作成された(そして削除された)のかということです。

于 2013-01-18T19:16:41.757 に答える