これが機能することに驚いています:
double x = 3;
double y = 2;
(x *= 2) += y;
std::cout << x << std::endl;
結果は 8 で、プログラマーが達成しようとしているように見えます。しかし、代入演算子は右辺値を返すと思っていました-どのようにして右辺値の結果に代入できるのでしょうか?
これが機能することに驚いています:
double x = 3;
double y = 2;
(x *= 2) += y;
std::cout << x << std::endl;
結果は 8 で、プログラマーが達成しようとしているように見えます。しかし、代入演算子は右辺値を返すと思っていました-どのようにして右辺値の結果に代入できるのでしょうか?
組み込み型の代入演算子は、C++ では左辺値を返します (C とは異なります)。しかし、シーケンスポイントを介在させずにオブジェクトを変更するためにそれを使用することはできないため、あなたの例は未定義の動作です (C++03 では、C++11 はここで大きく変更され、結果の 1 つがコードを作成したことを覚えているようです)定義されています)。
未定義の動作に関する状況に関係なく、次のように記述した方がよいでしょう:
x = 2 * x + y;
はるかに読みやすいです。代入演算子の結果が左辺値になるという事実は、結果がすぐに参照にバインドされている場合にのみ実際に使用できます。
T&
SomeClass::f()
{
// ...
return aTinSomeClass += 42;
}
それでも、私はそれを2つのステートメントで書きます。
(C++ の一般的な規則は、演算子の結果がメモリ内のオブジェクトの値に対応する場合、それは左辺値であるというものです。C には一般的な規則はありませんでした。)
C++ では、§5.17/1 に従って、複合代入演算子は左辺値を返します。
代入演算子 (
=
) と複合代入演算子はすべて右から左にグループ化されます。すべてが左オペランドとして変更可能な左辺値を必要とし、左オペランドを参照する左辺値を返します。
この場合、 を使用すると*=
、オブジェクトを示す左辺値が返され、x
これが演算子の左オペランドとして使用され+=
ます。
おそらく、右辺値を返す and+
のような単純な算術演算子について考えているでしょう。*
C では、これらの演算子は左辺値を返さないため、結果をさらに代入することはできません。
C++ では、複合代入演算子 ( など*=
) を含む代入演算子の結果は左辺値であり、したがって代入可能です。
Cではr値であるため、コードは無効なCコードです。