でcpprefC++17 までは、次のことが当てはまります。
のようなコードは、が呼び出された後に例外をスローする
f(std::shared_ptr<int>(new int(42)), g())
とメモリ リークを引き起こす可能性がありますが、 2 つの関数呼び出しが交互に行われることはないため、 は安全です。g
new int(42)
f(std::make_shared<int>(42), g())
C++17 で導入されたどの変更によってこれが適用できなくなったのか疑問に思っています。
ベストアンサー1
関数の引数の評価順序は、P0400R0。
変更前は、関数の引数の評価は、互いに順序付けられていませんでした。つまり、 の評価がg()
の評価に挿入される可能性がありstd::shared_ptr<int>(new int(42))
、引用されたコンテキストで説明されている状況が発生します。
変更後、関数の引数の評価は、インターリーブなしで不確定に順序付けられます。つまり、 のすべての副作用は、 のstd::shared_ptr<int>(new int(42))
副作用の前または後に発生しますg()
。ここで、 がスローする可能性があるケースを考えてみましょうg()
。
のすべての副作用が の
std::shared_ptr<int>(new int(42))
副作用の前に発生した場合g()
、割り当てられたメモリは のデストラクタによって解放されますstd::shared_ptr<int>
。のすべての副作用が の
std::shared_ptr<int>(new int(42))
副作用の後に発生する場合g()
、メモリの割り当ても行われません。
どちらの場合でも、メモリ リークは発生しません。