10

理由が値を返さないという質問への回答で、例外安全性の理由(コピーコンストラクターがスローした場合はどうなりますか)が原因であるstd::stack::pop() と主張しました。pop

@Konradは、moveセマンティクスでは、これはもはや関係がないとコメントしました。これは本当ですか?

AFAIK、moveコンストラクターは可能 throwですが、おそらくnoexceptそれを使用しても達成できます。

ボーナスポイントについては、この操作でどのスレッドセーフが保証されますか?

4

2 に答える 2

3

おまけの質問に関しては、それはスレッドセーフを提供しません。例として、 のほとんどの実装にstd::vector3 つのデータ要素があるとします (メモリの先頭へのポインタ、使用済みデータの末尾を超えるポインタ、割り当てられたメモリの末尾を超えるポインタ)。移動セマンティクスを使用すると、値を再割り当てしてコピーする必要なくベクターの内容を移動できますが、これはスレッド セーフとは関係ありません。構造体をスレッド セーフにするために、スレッド セーフな構造を使用する必要があります (移動は決してアトミックであることを意味しないため) 。

于 2010-04-12T07:27:27.230 に答える
3

もちろん、すべての型が移動可能というわけではなく、C++0x では移動コンストラクターのスローも許可されています。右辺値からオブジェクトを構築するとスローされる可能性がある限り、例外セーフにすることはできません。ただし、ムーブ セマンティクスを使用すると、右辺値ソースが与えられた場合に、スロー構成できない多くの型を使用できます。

これに対する条件付きサポートは、SFINAE で行うことができます。しかし、そのような条件付きメンバー関数がなくても、書くことを止めるものは何もありません:

auto stack = ...;
auto elem = std::move_if_noexcept(stack.back());
stack.pop_back();

これは、移動コンストラクターが強力な保証を提供しない場合でも、強力な例外保証を行います。

于 2010-04-12T07:13:39.223 に答える