// platform-specific handle type for resources. typedef unsigned int handle_type ; // platform-specific resource allocator and de-allocator function. handle_type allocator() ; void deallocator( handle_type handle ) ; // user defined deleter. struct handle_deleter { typedef handle_deleter type ; typedef handle_type pointer ; void operator () ( handle_type handle ) const { deallocator( handle ) ; } } ; int main() { // allocate a resource. // because of deleter, // unique_ptr< handle_type, handle_deleter >::pointer is type of handle_type. // Not the handle_type * std::unique_ptr< handle_type, handle_deleter > handle( allocator() ) ; // move a resource to shared_ptr. // ill-fomed. // Because shared_ptr expects handle_type *. std::shared_ptr< handle_type > ptr( std::move(handle) ) ; }
これはまずい。unique_ptrと違いすぎる。これでは、自前デリーターが使えない。
shared_ptrは、unique_ptrに合わせるべきではないだろうか。
しかしその場合、現行のshared_ptrにある、便利でType Erasureなデリーター指定が使えない。難しいものだ。
unique_ptr から shared_ptr へと所有の管理方法を変更することは、かなりレアケースだと思います。
ReplyDelete普通 shared_ptr に移すことが分かっているのなら、最初から unique_ptr を使うことはないでしょう。
あ、ちょっと論点が間違ってました…
ReplyDeleteshared_ptr がそういうインターフェースになっているのには訳がありますから (http://www.ustream.tv/recorded/2981654)、現状のインターフェースのほうがよいと考えます。
その上で、例のような unique_ptr の使い方は、 shared_ptr でも を使うことを想定していないような使い方なので、これがうまくいかないのは仕方ないでしょう。
This comment has been removed by the author.
ReplyDelete(<>がHTMLタグと認識されてしまったようなので投稿しなおします)もし、shared_ptrに手を加えるとしたら、現在template<typename T> class shared_ptr;のようになっているところをtemplate<typename T, typename PointerType = T*> class shared_ptr;とするのはどうでしょうか。上記の場合、std::unique_ptr< handle_type, handle_deleter >からstd::shared_ptr< handle_type, handle_type >へ変換可能とする(一般にremove_reference<D>::type::pointerからPointerTypeへ暗黙の変換が可能ならよしとする)のです。
ReplyDeleteそれはジェネリックではありませんね。
ReplyDelete