2013-10-25 12 views
17

コンテナクラスを作成します。このコンテナには2つの特殊化された挿入メソッドがあります。まず、コピーコンストラクタを使用して、あるコンテナから別のコンテナ要素にデータをコピーします。コピーコンストラクタが例外をスローすると、何も起こらないようにコンテナに対するすべての変更を元に戻すだけです。例外安全なコードと移動セマンティクス

第2の特殊化は、移動コンストラクタを使用し、物事が複雑になる場所を使用します。あるコンテナから別のコンテナ要素へ要素を移動すると、コンストラクタは例外をスローできます。これが起こった場合 - 私はいくつかの要素が移動され、他の要素が元の場所にとどまっていると、本当に面倒な状態になっています。要素を元に戻そうとすると、別の例外が発生する可能性があります。

例外的に安全な方法で、または例外の安全性と移動のセマンティクスを互いに排他的に書くことは可能ですか?

答えて

22

例外の影響を受けやすいコードを書くときにはstd::move_if_noexceptを使用しますが、それでもコンパイル時に安全な場合は移動のセマンティクスを使用します。

詳しくは、Scott Meyers' talk at GoingNative 2013を参照してください。

PS:あなたのものがコピーコンストラクターでない場合は、ムーブコンストラクターのスロー/ノットに関係なくスティルを移動するつもりです。

+0

私は "PS"を手に入れません。あなたは詳しく説明できますか? –

+1

移動がスローされる可能性がある場合は、std :: move_if_noexceptフォールバックをコピーします。しかし!あなたのものにコピーコンストラクタがない場合は、std :: move_if_noexceptが 'Meh'と言って移動します(それ以外は本当に何ができますか?)。おそらく例外が発生し、コンテナが本当に悪い状態になる可能性があります。 –

+2

それをIMO ...と定義するのはひどい選択です。代わりにコンパイル時エラーを引き起こすあなた自身のバージョンを( '&& std :: is_copy_constructible :: value'なしで)作ることができます。 – Joe

1

これを行うには、コンストラクタの委譲を使用する方法があります。委譲していないコンストラクタ(引数を持たないコンストラクタ、おそらくメンバーをデフォルトに設定する)が終了し、コンストラクタ委譲がスローされた場合、標準ではローカルステートが削除されます。このようにして、漏出することはありません。今日はちょうどthis talkでこれを学んだ。

ところで、STLがまだあなたのために設定していないコンテナのタイプは何ですか?

+0

Cuckooハッシュテーブル:) – Lazin

+0

それは聞いたことがありませんが、それは[ウィキペディア](http://en.wikipedia.org/wiki/Cuckoo_hashing)まで説明します^^ – HaMster

関連する問題