デフォルトコンストラクトされたshared_ptrオブジェクトは空(empty)となる。一方、明示的にnullptrを与えてコンストラクトしたshared_ptrオブジェクトは “ヌルポインタを所有(own)する” *1。この場合はshared_ptrオブジェクト破棄時にカスタムデリータが呼ばれる。

#include <memory>
#include <iostream>

int main()
  auto custom_deleter = [](void* p){
    assert(p == nullptr);
    std::cout << "deleter called" << std::endl;

  std::shared_ptr<void> sp(nullptr, custom_deleter);
}  // 標準出力に"deleter called"が出力される


(snip) A shared_ptr object is empty if it does not own a pointer.

constexpr shared_ptr() noexcept;
1 Effects: Constructs an empty shared_ptr object.
2 Postconditions: use_count() == 0 && get() == 0.

template <class Y, class D> shared_ptr(Y* p, D d);
template <class D> shared_ptr(nullptr_t p, D d);

9 Effects: Constructs a shared_ptr object that owns the object p and the deleter d. (snip)
10 Postconditions: use_count() == 1 && get() == p.

1 Effects:

  • If *this is empty or shares ownership with another shared_ptr instance (use_count() > 1), there are no side effects.
  • Otherwise, if *this owns an object p and a deleter d, d(p) is called.
  • Otherwise, *this owns a pointer p, and delete p is called.

追記:"empty" の定義が曖昧?


N3337は "A shared_ptr object is empty if it does not own an object a pointer." とすべきかも。


*1:ヌルポインタ定数として NULL や 0 を指定した場合も同様の動作となる。