34

私は過去数年間C++でコーディングしています。しかし、私が理解できなかった質問が1つあります。質問したいのですが、すべてC ++の一時的なものですか、右辺値ですか?

いいえの場合、コードで一時的に生成される値が左辺値である例を誰かに教えてもらえますか?

4

7 に答える 7

46

いいえ。

C ++言語仕様は、あなたが求めているような単純な主張をすることは決してありません。言語標準のどこにも、「すべての一時オブジェクトは右辺値である」とは書かれていません。さらに、C ++言語で右辺値であるというプロパティはオブジェクトのプロパティではなく、式のプロパティ(つまり、その結果のプロパティ)であるため、質問自体は少し誤称です。これは、実際には言語仕様で定義されている方法です。さまざまな種類の式について、結果が左辺値の場合と右辺値の場合を示します。特に、これは実際には、アクセスを実行するために使用される式の特定の形式に応じて、一時オブジェクトに左辺値としてだけでなく右辺値としてもアクセスできることを意味します。

たとえば、リテラル2 + 3式の結果は明らかに右辺値であり、型の一時的なものintです。単項はオペランドとして左辺値を必要とするため、単項&を適用することはできません。&

&(2 + 3); // ERROR, lvalue required

ただし、ご存知のとおり、定数参照は、次のように一時オブジェクトにアタッチできます。

const int &ri = 2 + 3;

この場合、参照は一時的なものに添付され、一時的なものの寿命を延ばします。ri明らかに、参照は常に左辺値であるため、一度実行すると、左辺値とまったく同じ一時的なものにアクセスできます。たとえば、単項&を参照に簡単かつ合法的に適用し、一時的なものへのポインタを取得できます

const int *pi = &ri;

そのポインタは、一時が持続する限り完全に有効なままです。

this一時オブジェクトへの左辺値アクセスのもう1つの明らかな例は、ポインターを介してクラス型の一時オブジェクトにアクセスする場合です。の結果*thisは左辺値です(データポインタに適用された単項の結果の場合は常にそうであるように*)が、実際のオブジェクトが簡単に一時的なものになる可能性があるという事実は変わりません。与えられたクラスタイプでは、言語標準で明示的に述べられているようにT、式は右辺値ですが、式を介してアクセスされる一時オブジェクト(の明らかな実装を使用)は左辺値です。前の例とは異なり、このメソッドを使用すると、一時オブジェクトを参照する非定数の左辺値をすぐに取得できます。T()*T().get_this()T::get_this()

したがって、この場合も、オブジェクトを「見る」ために使用する式の種類(アクセスパスの種類)に応じて、まったく同じ一時オブジェクトが右辺値または左辺値として簡単に「表示」される可能性があります。

于 2010-01-27T09:51:18.837 に答える
10

Prasoon Sauravは、すでに非常に優れたclc++スレッドをリンクしています。そこで、James Kanzeは、質問が本当に意味をなさない理由を説明します。要約すると、次のようになります。

  • rvalue-nessは、式の(ブール)プロパティです。各式は、左辺値または右辺値のいずれかです。
  • 一時的なものは表現ではありません

そのため、質問は意味がありません。

良い例は次のコードです。

int main() {
  const int& ri = 4;
  std::cout << ri << std::endl; 
}

値を持つ一時的なint4は式ではありません。ri印刷される表現は一時的なものではありません。これは左辺値であり、一時的なものを指します。

于 2010-01-27T08:51:04.973 に答える
1

その配列演算子は参照を返しますが、参照を返す関数は同じことを行うと見なすことができますか?すべての参照はconstですが、左辺値にすることもできますが、参照自体ではなく、参照内容を変更します。*同じことがオペレーターにも当てはまります。

*(a temp pointer) = val;

私は、参照を取得した関数に一時値を渡すコンパイラを使用していたことを誓います。

だからあなたは行くことができます:

int Afunc()
{
   return 5;
}

int anotherFunc(int & b)
{
    b = 34;
}


anotherFunc(Afunc());

現在、それを可能にするものを見つけることができませんが、一時値を渡すことができるようにするには、参照がconstである必要があります。

int anotherFunc(const int & b);

とにかく、参照は左辺値と一時的なものにすることができます。トリックは、それ自体が変更されるのではなく、参照するものだけです。

->演算子を演算子として数える場合、一時ポインターは左辺値にすることができますが、同じ条件が適用されます。変更されるのは一時ポインターではなく、それが指すものです。

于 2010-01-27T07:32:35.207 に答える
0

配列のインデックス作成操作は一時的なものであり、左辺値でもあります。a[10] = 1のようなものは、探しているものの例です。左辺値は一時的な計算ポインターです。

于 2010-01-27T07:20:11.737 に答える
0

それはあなたが一時変数と考えるものに依存します。あなたは次のようなものを書くことができます

#include <stdio.h>
int main()
{
    char carray[10];
    char *c=carray+1;
    *(c+2+4) = 9;
    printf("%d\n",carray[7]);
    return 0;
}

これはVisualStudiosとGCCで実行されます。コードパッドでコードを実行できます

割り当てたいのですが、(c + 2 + 4)を右辺値と見なします。逆参照すると、左辺値になります。つまり、すべての一時的なものは右辺値です。ただし、逆参照することで、右辺値(つまり一時的な値)を左辺値にすることができます

于 2010-01-27T07:50:52.337 に答える
0

簡単な答え:はい。ただし、要点を証明するには、あらゆる種類の一時的な問題に対処する必要があるため、標準を引用するつもりはありません。定義上、一時的なものの有効期間は1つのステートメントであるため、1つのステートメントに物事を割り当てることは、せいぜい貧弱なスタイルになります。

興味深い答え:コピーの省略は、一時オブジェクトを左辺値オブジェクトと同一にすることができます(多くの場合、作成します)。例えば、

MyClass blah = MyClass( 3 ); // temporary likely to be optimized out

また

return MyClass( 3 ); // likely to directly initialize object in caller's frame

編集:それらの場合に一時的なオブジェクトがあるかどうかの質問に関しては、§12.8/15は言及します

省略されたコピーのターゲットに一時オブジェクトを直接構築することにより、コピー操作を省略できます。

これは、左辺値と同一である可能性のある一時オブジェクトがあることを示します。

于 2010-01-27T08:42:48.090 に答える
-2

いいえの場合、コードで一時的に生成される値が左辺値である例を誰かに教えてもらえますか?

const float次のコードは、コンパイラによって作成されたタイプの一時オブジェクトへの定数参照をバインドします。

int i;
const float &cfr = i;

動作は「あたかも」のようです:

int i;
const float __tmp_cfr = i; // introduced by the compiler
const float &cfr = __tmp_cfr;
于 2011-12-07T09:55:27.673 に答える