web-dev-qa-db-ja.com

一時オブジェクトへの非const参照がないのはなぜですか?

重複の可能性:
const参照は一時的なものの寿命を延ばしますか?
一時的な寿命を延ばす

C++では、const参照にのみ一時オブジェクトを割り当てることができます。一時オブジェクトを参照に割り当てることはできません。

例えば:

String& a = String("test");         // Error
const String& a = String("test");   // Ok

この結果をググったらどこでも、私は次の答えしか見ません

  1. 一時オブジェクトを変更すると、識別できない問題が発生する
  2. 一時オブジェクトの変更は危険です
  3. ある時点で、それが一時変数であることを忘れるでしょう

一時的なオブジェクトはステートメントの後に消えると言われています。したがって、変更しないでください。

C++の場合、一時オブジェクトの変更をブロックすることに熱心である場合、一時オブジェクトの読み取りをブロックする必要がありますか?一時オブジェクトが消滅した場合、そこからコンテンツを読み取っても意味がないのでしょうか?権限が発生する可能性のある可能性のあるケースには、読み取りも含まれます。

では、なぜ書き込みだけをブロックして読み取りを許可しているのでしょうか。

しっかりとしたc ++コードの説明を教えてください。

いくつかの選択肢を指摘することにより、質問を逸脱しないでください。一時オブジェクトに対してconst int&が許可され、int&が許可されない理由をコードで教えてください。

1つは&&がそこにあると言います..私の質問は異なります..もう1つは、変更は反映されませんと言います。変更はconst int&でも反映されません。例:ダブルa; Const int&i = a; a ++; i ..には影響しません。

47
user738471

一時変数への参照を許可しない元のケースは、関数パラメーターに関するものでした。これが許可されていたとしましょう:

void inc(double& x)
{ x += 0.1; }

int i = 0;
inc(i);

iが変更されないのはなぜですか?

30
Bo Persson

C++の場合、一時オブジェクトの変更をブロックすることに熱心である場合、一時オブジェクトの読み取りをブロックする必要がありますか?一時オブジェクトが消滅した場合、そこからコンテンツを読み取っても意味がないのでしょうか?

いいえ、オブジェクトを読み取ることは完全に賢明です。それが将来消滅するからといって、データを読み取ることを意味するわけではありませんnowは無意味です。

_open_file(std::string("foo.txt"));
_

std::string("foo.txt")open_file()の呼び出し後に存在しなくなる一時的なものですが、存在する間に含まれるデータは非常に重要です。

テンポラリーが非const参照にバインドすることを許可しないことの合理的根拠は、テンポラリーへの書き込みに関する実際の基本的な問題ではありません。実際、多くの場所で、C++は一時を変更できるように完全に満足しています。

_std::string("foo") = "bar";
_

設計者は、(おそらく「出力パラメータ」の一般的なイディオムが原因で)十分な数の問題を引き起こし、同様の値の何かを有効にせずに一時的なものを非constにバインドすることを禁止するという設計上の決定を行っただけだと感じただけです。参照。

右辺値参照を使用すると、以前は禁止されていたものを正確に実行できます。

_void foo(int &&output) {
    output = 1;
}

foo(2);
_

これは問題なく機能しますが、あまり役に立ちません。

13
bames53

コピーに非常にコストのかかる一時オブジェクトがある場合は、const&を後で使用するために別の変数にコピーするのではなく、そのオブジェクト(関数の戻り値など)に追加します。テンポラリへの一定の参照を取得すると、そのテンポラリの寿命が参照が存続する期間まで延長され、読み取り可能な状態にアクセスできるようになります。

変数を変更したい場合は、非const参照としてのみエイリアスされた一時的なものではなく、実際のインスタンスが存在する可能性があるため、書き込みは許可されません。

3
Mark B

これには論理的な理由があります。この行に実際に必要なものを考えてみてください。

_String& a = String("test");         // Error
_

参考にしたい。参照は、参照先のオブジェクトに関連しています。オブジェクトのアドレスと同様(参照はアドレスではありませんが、この方法で説明が明確になります)。実際には、String("test")のようなアドレスを取得しようとします。しかし、そのオブジェクトは次の行ですぐに消えてしまうので、そのオブジェクトが存在しない場合、そのアドレスのポイントは何ですか? aが意味のないものを指すようになりました...

2番目の質問については、一時オブジェクトをまとめて許可することのポイントは何でしょうか。まあ、それには何の問題もありません。たとえば、Stringオブジェクトを関数に渡して、その文字列に対応する変更された文字列を返す場合を考えます。関数DoubleStringを呼び出しましょう。そうする代わりに

_String s("hello ");
String s2 = DoubleString(s);
_

短くて便利なフォームを使用できます

_String s2 = DoubleString(String("hello "));
_

一時オブジェクトString("hello ")はコード行全体で存続します。つまり、DoubleStringに送信された後もそのままであるということです。行全体が終了したときにのみ破棄されます。

0
Israel Unterman