std::shared_ptr<void>
は、代入された任意の型のデストラクタが適切に呼び出されるが、std::unique_ptr<void>
はできない。この提案は、それをなんとかしようというもの。
技術的には、こういうことをする:
#include <iostream> #include <memory> struct X { ~X() { std::cout << "destructor" << std::endl; } }; struct void_deleter { std::function<void(void*)> deleter; template <class F> void_deleter(F f) { deleter = f; } void operator()(void* p) const noexcept { deleter(p); } }; int main() { std::unique_ptr<void, void_deleter> p( new X(), [](void* p) { delete static_cast<X*>(p); } ); }
出力:
destructor
つまり、任意の型のポインタが代入された時点で、「void*
型のポインタから任意の型のポインタにキャストしてdelete
する」関数オブジェクトを持たせる。これも一種のType Erasure。
ここではstd::function
でそのような関数オブジェクトを保持しているが、実際の提案では、キャプチャなしのラムダ式を関数ポインタに変換して持っているため、ほぼコストがない。
このような実装を、std::unique_ptr
のvoid
に対する特殊化として用意し、std::unique_ptr
のコンストラクタ/代入演算子内部でこういうことをする、というのがこの提案。