Boost.PPでmake_uniqueを実装してみた
(std|boost)::shared_ptrには、それを生成するためのヘルパ関数make_sharedがありますが、std::unique_ptrにはそれに相当するものがありません。そこで、Boost.PPを使って簡単に実装してみました。
make_unique_nvt.hpp
#ifndef BOOST_PP_IS_ITERATING #ifndef IORATE_MAKE_UNIQUE_NVT_HPP_INCLUDED #define IORATE_MAKE_UNIQUE_NVT_HPP_INCLUDED #include <memory> #include <utility> #include <boost/preprocessor/iteration/iterate.hpp> #include <boost/preprocessor/cat.hpp> #include <boost/preprocessor/repetition.hpp> #ifndef IORATE_MAKE_UNIQUE_MAX_ARITY #define IORATE_MAKE_UNIQUE_MAX_ARITY 10 #endif namespace iorate { #define BOOST_PP_ITERATION_LIMITS (0, IORATE_MAKE_UNIQUE_MAX_ARITY - 1) #define BOOST_PP_FILENAME_1 "make_unique_nvt.hpp" #include BOOST_PP_ITERATE() } // namespace iorate #endif // IORATE_MAKE_UNIQUE_HPP_INCLUDED #else // BOOST_PP_IS_ITERATING #define n BOOST_PP_ITERATION() #define IORATE_MAKE_UNIQUE_forward(z, m, data) \ std::forward<BOOST_PP_CAT(A, m)>(BOOST_PP_CAT(a, m)) template <class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class A)> inline std::unique_ptr<T> make_unique(BOOST_PP_ENUM_BINARY_PARAMS(n, A, &&a)) { return std::unique_ptr<T>( new T(BOOST_PP_ENUM(n, IORATE_MAKE_UNIQUE_forward, ~)) ); } #undef IORATE_MAKE_UNIQUE_forward #undef n #endif // BOOST_PP_IS_ITERATING
VC10+Boost1.45.0で動作を確認しました。デリータは指定できません。
もっとも、Variadic Templatesが使える環境ではこんな面倒なことをする必要はありません。以下のように書けます。
make_unique.hpp
#include <memory> #include <utility> namespace iorate { template <class T, class ...Args> inline std::unique_ptr<T> make_unique(Args &&...args) { return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); } } // namespace iorate
いいですねVariadic Templates.