GCC 4.4 + Boost 1.40.0だと以下のコードはコンパイルが通りません。
#include <tuple> #include <boost/fusion/include/vector.hpp> template <class Args> struct hoge; template <class... Args> struct hoge<boost::fusion::vector<Args...>> { // エラー! typedef std::tuple<Args...> type; }; int main() {}
これがエラーになるのは、GCC 4.4時点での可変引数テンプレートの実装では
固定長テンプレートパラメータを可変長テンプレートの部分特殊化として使用できないからだそうです。
(fusion::vectorはtemplate
# これがコンパイル通ったとしても、fusion::vectorの後ろはfusion::void_で埋められてるのでフィルタをかけないといけません
仕方がないので、fusion::vectorを再帰で回してstd::tupleに変換するメタ関数を書いてみました。
(boost::tupleだと固定長テンプレートパラメータとなり、扱いにくいのでstd::tupleにしてます)
#include <tuple> #include <boost/type_traits.hpp> #include <boost/mpl/int.hpp> #include <boost/fusion/include/vector.hpp> #include <boost/fusion/include/value_at.hpp> #include <boost/fusion/include/size.hpp> #include <boost/fusion/include/pop_front.hpp> template <class List, class FVector, int N> struct fuvector_to_tuple_impl; template <class... Args, class FVector, int N> struct fuvector_to_tuple_impl<std::tuple<Args...>, FVector, N> { typedef typename fuvector_to_tuple_impl< std::tuple<Args..., typename boost::fusion::result_of::value_at<FVector, boost::mpl::int_<0>>::type>, typename boost::fusion::result_of::pop_front<FVector>::type, N - 1 >::type type; }; template <class... Args, class FVector> struct fuvector_to_tuple_impl<std::tuple<Args...>, FVector, 0> { typedef std::tuple<Args...> type; }; template <class FVector> struct fuvector_to_tuple { typedef typename fuvector_to_tuple_impl< std::tuple<>, FVector, boost::fusion::result_of::size<FVector>::value >::type type; }; int main() { typedef boost::fusion::vector<int, char, double> types; static_assert(boost::is_same<fuvector_to_tuple<types>::type, std::tuple<int, char, double> >::value, "not same"); }