"stl 例外安全 vector push_back"

こんなリファラが.折角だからstd::vector(std:deque)の例外安全性の表でも作ってみましょうかね.本来なら実装依存ですけれど,まぁこの表より例外安全性緩める理由は無いはず(というか自分がstd::vector作るならこうする).

std::vectorの例外安全性

value_typeのコピーコンストラクタ及び代入強いnothrow
コンストラク強い強い
デストラクnothrownothrow
代入強い強い
push_back強い強い
pop_backnothrownothrow
insert(最後尾はpush_backと同じ)基本強い
erase(最後尾はpop_backと同じ)基本強い
resize(要素数が減る場合)nothrownothrow
resize(要素数が増える場合)強い強い
reserve強い強い
clearnothrownothrow

  1. 上の表の大前提としてvalue_typeのデストラクタはnothrow
  2. std::vectorの内部ではvalue_typeのデフォルトコンストラクタは一切使われない(デフォルト引数としてのみ現れる)ため,value_typeのデフォルトコンストラクタから飛んでくる例外に対しては全て強い例外安全性が達成される(上の表でnothrowなものはnothrow)
  3. std::dequeの場合も上とほぼ同じでpush_front, pop_front(先頭におけるinsert/erase)はstd::vectorのpush_back, pop_backに準じる.

ご存知のようにstd::vector(std::deque)に対して中間でinsert/eraseをやると他の要素の移動を伴う.この際に呼ばれるvalue_typeのコピーコンストラクタ(代入)から例外が飛んでくるとロールバックのしようがないので基本的な例外安全しか達成できない.ただし,std::dequeはこれに関して強い例外安全を達成できるような実装も可能なはず(若干オーバーヘッド高いけれど).