OK、最初に関連する可能性のあるいくつかのこと:
Clang 3.1 コンパイラを C++11 モードで使用し、標準ライブラリを libc++ に設定しています。
私は C++11 に慣れようとしていますが、そうしているうちに奇妙な動作に出くわしました。それはClangまたはlibc ++の癖かもしれませんが、私はC ++標準語を話すことができず、C ++ 11をサポートする他のコンパイラにアクセスできないため、実際に確認することはできません。インターネットとスタックオーバーフローを検索しました関連するものを見つけることなく、私の能力を最大限に発揮します...だからここに行きます:
shared_ptr / unique_ptr を使用して単純なリソースの RAII を実装する場合、削除時の null ポインターに関してそれらの動作が異なるようです。通常、ヌル ポインターを削除する必要はないことは認識していますが、少なくとも 2 つの STL スマート ポインター間で動作が一致することを期待していました。
特定のケースでは、次のコードを検討してください。
{
auto Deleter = [](void *){cout << "It's later!" << endl;};
shared_ptr<void> spDoSomethingLater(nullptr, Deleter);
unique_ptr<void, void (*)(void *)> upDoSomethingLater(nullptr, Deleter);
cout << "It's now!" << endl;
}
これから、次のいずれかの出力が期待されます。
a) ポインターがヌルであっても、両方のデリータが呼び出された場合:
"It's now!"
"It's later!"
"It's later!"
b) ポインターが null であるため、どちらのデリータも呼び出されない場合:
"It's now!"
しかし、私はこれらのケースのどちらも観察しません。代わりに、私は次のことを観察します。
"It's now!"
"It's later!"
これは、一方のデリータが呼び出され、もう一方が呼び出されていないことを意味します。さらに調べてみると、shared_ptr のデリータは null 値を保持しているかどうかに関係なく呼び出されますが、unique_ptr のデリータは null 値を保持していない場合にのみ呼び出されることがわかりました。
私の質問: これは実際に標準で指定されている正しい動作ですか? もしそうなら、なぜこのように 2 つの STL タイプ間で指定された動作が異なるのでしょうか? そうでない場合、これは libc++ に報告すべきバグですか?