web-dev-qa-db-ja.com

通常の参照ではなくconst参照でR値を渡すことが許可されているのはなぜですか?

タイトルが示すように、通常の参照ではなく定数参照によってR値(リテラル)を渡すことが許可されている理由

_void display(const int& a)
{
cout << a ;
}
_

display(5)を呼び出すと機能しますが、constがないと機能しません****** const参照がR値を指し続ける方法(無名変数)******

21
Mekacher Anis

最後の質問について:

const参照がR値(匿名変数)を指し続ける方法

これが答えです 。 C++言語によると、ローカルのconst参照は、一時的な値の有効期間を包含スコープの終わりまで延長しますが、コピー構築のコストを節約します(つまり、代わりにローカル変数を使用した場合)。

26
Tanz87

オブジェクトは、boxの中に値が含まれていると考えてください。ボックスには名前タグがある場合とない場合があります。つまり、ボックスwith名前タグをvariableとして、ボックスなし名前タグをliteralとして。名前タグがあるかどうかに関係なく、私たちは箱を持っています。


Referenceは、名前タグをボックスに追加する方法です。

int a = 5;
int &b = a;

ボックスにtwo名前タグがあります(値5内部)。

const int &c = 5;

ボックスがあります。


以前に名前を付けたことのないボックスの新しい名前は、constとしてマークする必要があります。ボックス内の値はその名前で変更できるため、literalボックスに対して(発生を許可されない)発生しないようにします。

12
NERDYLIZARD

リテラルの定義に戻ります。リテラルは定数です。たとえば、数値5の値は変更されませんが、変数に5の値が割り当てられた状態から別の値に変更される場合があります。リテラルを参照渡しすることは、関数がリテラルを変更する可能性があることを意味します。これは、定義上、リテラルに対して行うことはできません。そのため、言語ではconstを使用して変更する必要があります。 C++でリテラルを変更できるとは思わないかもしれませんが、リテラル値は変更できないことをプログラマーに思い出させるために、この規則を強制しています。

それがあなたの質問に答えることを願っています!

5
Durendal

リテラルは定数だからです。 1を2にすることはできず、_"abd"_を_"edf"_にすることはできません。

C++で非const参照によるリテラルの取得が許可されている場合、次のいずれかになります。

  1. リテラルがその意味を動的に変更できるようにし、1を2にできるようにする必要があります。
  2. プログラマーがリテラルを参照しない参照を介してのみ値を変更するように細心の注意を払い、間違っている場合は未定義の動作を呼び出すことを期待してください。

(1)_x == 1_はコンテキストに応じて「is x equal to 2」を意味する可能性があるため、プログラムにカオスを作成し、(2)はvoid display(int& a)がリテラル参照を受け取るかどうか知っていますか?

これら2つのオプションはどちらも意味がないため、リテラルはconst参照でのみ渡すことができます。


実際、文字列リテラルから_char*_への非推奨の変換は、参照ではなくポインタであるにもかかわらず、ルールが意味をなす理由の良い例です。 _char*_が_"abc"_を指すようにすることは許可されていますが、実際に_char*_の「変更可能性」属性を利用してchar要素の1つを変更しようとすると、結果は未定義の動作で。これにより、非推奨の変換全体が危険になり、役に立たなくなります(非レガシーコードでは)。

あなたは言語の他のすべての部分でそのような問題を抱えたくないでしょうね?

2
Christian Hackl

R値は一時的なエバネッセントオブジェクトであり、読み取ることはできますが、破棄しようとしています。また、割り当ての左側にとどまることができない値でもあります(このようなゴーストに値を割り当てる意味はありますか?)

C++には、この種のエンティティを処理する非常に特殊な方法があります。 (非const)参照でr値を渡すことができる場合は、関数内から割り当てることもできます。したがって、r値が参照によって渡される場合、これはconst参照である必要があるという規則です。

ただし、実際にはr値の参照(&&)。したがって、最終的には一時オブジェクトを操作できますが、r値参照を使用して、本当に実行したい明示的なステートメントを作成する必要があります。

1
Emerald Weapon