カスタムでリターを使用するユーザ定義型に対して std::unique_ptr を特殊化する
そんな話が Lingr の C++ 部屋で出ていたので。
// 毎回カスタムデリータを設定するのが手間 std::unique_ptr<X, decltype(&X_deleter)> xp(new X(42), &X_deleter); // こう書けるようにしたい // std::unique_ptr<X> xp(new X(42));
[コード]
#include <memory> #include <iostream> struct X{ friend void X_deleter(X*); X(int value) : value(value){} int value; private: ~X(){}; }; void X_deleter(X* x){ std::cout << "X_deleter" << std::endl; delete x; } namespace std{ template <> struct unique_ptr<X, std::default_delete<X>> :unique_ptr<X, decltype(&X_deleter)> { explicit unique_ptr(X* p) : unique_ptr<X, decltype(&X_deleter)>(p, &X_deleter) {} }; } // namespace std int main(){ // std::unique_ptr<X, decltype(&X_deleter)> xp(new X(42), &X_deleter); std::unique_ptr<X> xp(new X(42)); std::cout << xp->value << std::endl; return 0; }
[出力]
42 X_deleter
一応、ユーザ定義型に対しての特殊化は許されているので仕様上は問題ないはず。
でもまぁ、特殊化するよりかはヘルパ関数を用意したほうがスマートだと思う。
template<typename... Args> std::unique_ptr<X, decltype(&X_deleter)> make_unique_X(Args... args){ return { new X(args...), &X_deleter }; } std::unique_ptr<X> xp(new X(42));