明確にするために、make_unique
式に1つだけではなく複数の割り当てがある場合にのみ、例外安全性が追加されます。正しいですか? たとえば、
void f(T*);
f(new T);
例外に対して完全に安全です(割り当てなどに関しては)。
void f(T*, T*);
f(new T, new T);
そうではないですよね?
ベストアンサー1
複数の割り当てがある場合だけでなく、異なる場所にスローできる場合も、次の点を考慮してください。
f(make_unique<T>(), function_that_can_throw());
対:
f(unique_ptr<T>(new T), function_that_can_throw());
2 番目のケースでは、コンパイラは (順番に) 次のように呼び出すことができます。
new T
function_that_can_throw()
unique_ptr<T>(...)
明らかに、function_that_can_throw
実際にスローするとリークが発生します。make_unique
このケースを防ぎます。
そしてもちろん、2 番目の割り当て (ご質問にあるように) は、 の特殊なケースにすぎませんfunction_that_can_throw()
。
一般的な経験則として、make_unique
コードの一貫性を保つために を使用してください。 が必要なときには常に正しい(つまり、例外安全)でありunique_ptr
、パフォーマンスにも影響がないため、 を使用しない理由はありません(実際にはないそれを使用すると、多くの問題が生じます。