swap には無送出保証の例外安全性が必要
『代入演算子の定石』では、swap
には無送出保証の例外安全性が必要だと書いた。これに対して、「これなら原子性保証だけで十分なのでは?」という疑問が湧くかもしれない。ちなみに、こういうコード:
some_class& operator = (const some_class& another) { some_class tmp_(another); swap(tmp_); return *this; }
確かに、swap
が例外を投げても (原子性保証があれば) 問題はないように見える。
実は、swap
の無送出保証を要請しているのはこの代入演算子ではない。これは、このクラスをメンバ変数に持ったり継承したりするクラスが例外安全な swap
を持つためのものだ。
たとえば、以下のようなクラスの swap
の実装を見るとこれが分かる。
class enclosing_class { public: void swap(enclosing_class& another) { m_someValue.swap(another.m_someValue); m_anotherValue.swap(another.m_anotherValue); } private: some_class m_someValue; another_class m_anotherValue; };
この enclosing_class:swap
に原子性保証を与えるためには、some_class::swap
や another_class::swap
に無送出保証が必要になる。
まとめると: