Variadic Templates で遊んでみた
と、いっても殆ど Boost.Fusion 回りの実装で時間を食ってしまいましたが。
Variadic Templates に対応した Boost.MPL Sequence が欲しかったので書いてみました。
ついでに Boost.Fusion も。
#include <boost/mpl/vector.hpp> #include <boost/mpl/apply.hpp> #include <boost/mpl/push_front.hpp> namespace mpl = boost::mpl; namespace detail{ template<typename Seq, typename Inserter, typename ...Args> struct variadic_sequence_impl; template<typename Seq, typename Inserter, typename T, typename ...Args> struct variadic_sequence_impl<Seq, Inserter, T, Args...> : mpl::apply< Inserter, variadic_sequence_impl<Seq, Inserter, Args...>, T >::type{}; template<typename Seq, typename Inserter, typename T> struct variadic_sequence_impl<Seq, Inserter, T> : mpl::apply<Seq, T>::type{}; template<typename Seq, typename Inserter> struct variadic_sequence_impl<Seq, Inserter> : mpl::vector<>{}; } // namespace detail{ template<typename Seq, typename Inserter, typename ...Args> struct variadic_sequence : detail::variadic_sequence_impl<Seq, Inserter, Args...>{}; // Boost.MPL Sequence template<typename ...Args> struct variadic_vector : variadic_sequence< mpl::vector1<mpl::_1>, mpl::push_front<mpl::_1, mpl::_2>, Args... >{}; #include <boost/mpl/equal.hpp> #include <boost/mpl/assert.hpp> #include <boost/mpl/push_back.hpp> typedef variadic_vector<int, char, double> seq; BOOST_MPL_ASSERT(( mpl::equal< seq, mpl::vector<int, char, double> > )); BOOST_MPL_ASSERT(( mpl::equal< mpl::push_back<seq, float>::type, mpl::vector<int, char, double, float> > )); // Boost.Fusion #include <boost/fusion/include/vector.hpp> #include <boost/fusion/include/push_front.hpp> #include <boost/fusion/include/as_vector.hpp> #include <utility> namespace fusion = boost::fusion; template<typename ...Args> struct variadic_fusion_vector : fusion::result_of::as_vector< variadic_sequence< fusion::vector1<mpl::_1>, fusion::result_of::push_front<mpl::_1, mpl::_2>, Args... > >::type{ typedef typename fusion::result_of::as_vector< variadic_sequence< fusion::vector1<mpl::_1>, fusion::result_of::push_front<mpl::_1, mpl::_2>, Args... > >::type base_type; template<typename ...UArgs> explicit variadic_fusion_vector(UArgs&&... args) : base_type(std::forward<UArgs>(args)...){} }; #include <iostream> #include <boost/fusion/include/io.hpp> int main(){ variadic_fusion_vector<int, char, double> v(1, 'a', 3.14); std::cout << v << std::endl; return 0; }
[出力]
(1 a 3.14)
Boost.Fusion が、やっつけだけど気にしない。
多分、decltype 使ったほうが楽。
あと書いてから気づいたんですけど Boost.MPL って Variadic Templates に対応していないんですかね。
Boost がどれぐらい C++0x に対応しているのかが気になります。
[boost]
ver 1.46.1
[参照]
http://blog.shandyba.com/2009/12/17/converting-variadic-template-arguments-pack-to-boost-mpl-sequence/
http://d.hatena.ne.jp/faith_and_brave/20110105/1294207038
http://d.hatena.ne.jp/faith_and_brave/20090820/1250765649