こんなリファラが.折角だからstd::vector(std:deque)の例外安全性の表でも作ってみましょうかね.本来なら実装依存ですけれど,まぁこの表より例外安全性緩める理由は無いはず(というか自分がstd::vector作るならこうする).
std::vectorの例外安全性
value_typeのコピーコンストラクタ及び代入 | 強い | nothrow |
---|---|---|
コンストラクタ | 強い | 強い |
デストラクタ | nothrow | nothrow |
代入 | 強い | 強い |
push_back | 強い | 強い |
pop_back | nothrow | nothrow |
insert(最後尾はpush_backと同じ) | 基本 | 強い |
erase(最後尾はpop_backと同じ) | 基本 | 強い |
resize(要素数が減る場合) | nothrow | nothrow |
resize(要素数が増える場合) | 強い | 強い |
reserve | 強い | 強い |
clear | nothrow | nothrow |
- 上の表の大前提としてvalue_typeのデストラクタはnothrow
- std::vectorの内部ではvalue_typeのデフォルトコンストラクタは一切使われない(デフォルト引数としてのみ現れる)ため,value_typeのデフォルトコンストラクタから飛んでくる例外に対しては全て強い例外安全性が達成される(上の表でnothrowなものはnothrow)
- std::dequeの場合も上とほぼ同じでpush_front, pop_front(先頭におけるinsert/erase)はstd::vectorのpush_back, pop_backに準じる.
ご存知のようにstd::vector(std::deque)に対して中間でinsert/eraseをやると他の要素の移動を伴う.この際に呼ばれるvalue_typeのコピーコンストラクタ(代入)から例外が飛んでくるとロールバックのしようがないので基本的な例外安全しか達成できない.ただし,std::dequeはこれに関して強い例外安全を達成できるような実装も可能なはず(若干オーバーヘッド高いけれど).