28

次のコード:

myQueue.enqueue('a');
myQueue.enqueue('b');
cout << myQueue.dequeue() << myQueue.dequeue();

コンソールに「ba」を出力します

その間:

myQueue.enqueue('a');
myQueue.enqueue('b');
cout << myQueue.dequeue();
cout << myQueue.dequeue();

「ab」を印刷するのはなぜですか?

coutが最初に最も外側の(;に最も近い)関数を呼び出して、その方法で機能しているように見えますが、それはその動作方法ですか?

4

3 に答える 3

31

演算子にはシーケンスポイントがない<<ため、コンパイラはどちらのdequeue関数も最初に自由に評価できます。保証されているのは、2番目のdequeue呼び出しの結果(式に表示される順序であり、必ずしも評価される順序ではない)が最初の呼び出し<<の結果に変換されることです(<<言っている)。

したがって、コンパイラはコードをこれらのいずれかのようなもの(疑似中間C ++)に自由に変換できます。これは完全なリストを意図したものではありません。

auto tmp2 = myQueue.dequeue();
auto tmp1 = myQueue.dequeue();
std::ostream& tmp3 = cout << tmp1;
tmp3 << tmp2;

また

auto tmp1 = myQueue.dequeue();
auto tmp2 = myQueue.dequeue();
std::ostream& tmp3 = cout << tmp1;
tmp3 << tmp2;

また

auto tmp1 = myQueue.dequeue();
std::ostream& tmp3 = cout << tmp1;
auto tmp2 = myQueue.dequeue();
tmp3 << tmp2;

これが、元の表現での一時的なものに対応するものです。

cout << myQueue.dequeue() << myQueue.dequeue();
|       |               |    |               |
|       |____ tmp1 _____|    |_____ tmp2 ____|
|                       |
|________ tmp3 _________|
于 2010-01-24T22:48:52.197 に答える
8

あなたの例からの呼び出し:

cout << myQueue.dequeue() << myQueue.dequeue();

operator<<関数を2回呼び出すと、次の式に変換されます。

operator<<( operator<<( cout, myQueue.dequeue() ), myQueue.dequeue() );
-------------------- 1
---------2

cout、の評価の順序myQueue.dequeue()は指定されていません。ただし、operator<<関数呼び出しの順序は、とでマークされているように明確に指定されてい1ます2

于 2010-01-24T23:41:59.847 に答える
5

C ++ 17以降、このコードの動作が変更されました。の左のオペランドは、オーバーロードされた演算子の場合でも<<、の右のオペランドの前にシーケンスされます。<<出力はになりますab

詳細については、「C ++ 17によって導入された評価順序の保証とは何ですか?」を参照してください。

于 2018-06-27T04:31:51.320 に答える