[fusion] [mpl] binary mpl::transform on empty std::tuple

Hello, Fusion provides adaptation code for treating an std::tuple as a Fusion sequence, and adaptation code for treating Fusion sequences as MPL sequences, but it seems that in the case of a binary mpl::transform on an empty std::tuple, the two do not work well together. When trying to compile the following code: #include <boost/mpl/transform.hpp> #include <boost/mpl/back_inserter.hpp> #include <boost/mpl/vector.hpp> #include <boost/fusion/adapted/std_tuple.hpp> #include <boost/fusion/adapted/mpl.hpp> #include <boost/fusion/mpl.hpp> struct first { template <typename T, typename U> struct apply { typedef T type; }; }; int main() { typedef std::tuple<> fusion_sequence1_type; typedef std::tuple<> fusion_sequence2_type; typedef boost::mpl::transform<fusion_sequence1_type, fusion_sequence2_type, first, boost::mpl::back_inserter<boost::mpl::vector<>> >::type result_type; } I get the following errors: In file included from test.cpp:4: In file included from boost/fusion/adapted/std_tuple.hpp:13: In file included from boost/fusion/adapted/std_tuple/detail/begin_impl.hpp:10: boost/fusion/adapted/std_tuple/std_tuple_iterator.hpp:45:13: error: implicit instantiation of undefined template 'std::tuple_element<0, std::tuple<> >' : std::tuple_element<Iterator::index, ^ boost/fusion/iterator/value_of.hpp:34:28: note: in instantiation of template class 'boost::fusion::std_tuple_iterator<std::tuple<>, 0>::value_of<boost::fusion::std_tuple_iterator<std::tuple<>, 0> >' requested here struct apply : Iterator::template value_of<Iterator> {}; ^ boost/fusion/iterator/value_of.hpp:51:15: note: in instantiation of template class 'boost::fusion::extension::value_of_impl<boost::fusion::iterator_facade_tag>::apply<boost::fusion::std_tuple_iterator<std::tuple<>, 0> >' requested here : extension::value_of_impl<typename detail::tag_of<Iterator>::type>:: ^ boost/fusion/iterator/mpl/fusion_iterator.hpp:46:45: note: in instantiation of template class 'boost::fusion::result_of::value_of<boost::fusion::std_tuple_iterator<std::tuple<>, 0> >' requested here typedef typename fusion::result_of::value_of<Iterator>::type type; ^ boost/mpl/iterator_category.hpp:27:22: note: in instantiation of template class 'boost::mpl::fusion_iterator<boost::fusion::std_tuple_iterator<std::tuple<>, 0> >' requested here typedef typename Iterator::category type; ^ boost/mpl/pair_view.hpp:152:20: note: in instantiation of template class 'boost::mpl::iterator_category<boost::mpl::fusion_iterator<boost::fusion::std_tuple_iterator<std::tuple<>, 0> > >' requested here typename iterator_category<iter1_>::type ^ boost/mpl/aux_/has_tag.hpp:20:1: note: (skipping 5 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all) BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_tag, tag, false) ^ boost/mpl/has_xxx.hpp:244:65: note: expanded from macro 'BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF' , boost::mpl::aux::type_wrapper<BOOST_MSVC_TYPENAME U::name>* = 0 \ ^ boost/mpl/transform.hpp:75:7: note: in instantiation of template class 'boost::mpl::fold<boost::mpl::pair_view<std::tuple<>, std::tuple<> >, boost::mpl::vector<mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::mpl::bind2<boost::mpl::push_back<mpl_::na, mpl_::na>, mpl_::arg<1>, boost::mpl::bind2<first, boost::mpl::bind1<boost::mpl::first<mpl_::na>, mpl_::arg<2> >, boost::mpl::bind1<boost::mpl::second<mpl_::na>, mpl_::arg<2> > > > >' requested here : fold< ^ boost/mpl/transform.hpp:114:1: note: in instantiation of template class 'boost::mpl::aux::transform2_impl<std::tuple<>, std::tuple<>, first, boost::mpl::back_inserter<boost::mpl::vector<mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na> > >' requested here BOOST_MPL_AUX_INSERTER_ALGORITHM_DEF(4, transform2) ^ boost/mpl/aux_/inserter_algorithm.hpp:44:7: note: expanded from macro 'BOOST_MPL_AUX_INSERTER_ALGORITHM_DEF' : aux::name##_impl<BOOST_MPL_PP_PARAMS(arity, P)> \ ^ boost/mpl/eval_if.hpp:38:22: note: in instantiation of template class 'boost::mpl::transform2<std::tuple<>, std::tuple<>, first, boost::mpl::back_inserter<boost::mpl::vector<mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na> > >' requested here typedef typename f_::type type; ^ boost/mpl/transform.hpp:138:1: note: in instantiation of template class 'boost::mpl::eval_if<boost::mpl::or_<boost::mpl::is_na<first>, boost::mpl::is_lambda_expression<std::tuple<> >, boost::mpl::not_<boost::mpl::is_sequence<std::tuple<> > >, mpl_::bool_<false>, mpl_::bool_<false> >, boost::mpl::transform1<std::tuple<>, std::tuple<>, first>, boost::mpl::transform2<std::tuple<>, std::tuple<>, first, boost::mpl::back_inserter<boost::mpl::vector<mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na> > > >' requested here AUX778076_TRANSFORM_DEF(transform) ^ boost/mpl/transform.hpp:125:22: note: expanded from macro 'AUX778076_TRANSFORM_DEF' typedef typename eval_if< \ ^ test.cpp:21:25: note: in instantiation of template class 'boost::mpl::transform<std::tuple<>, std::tuple<>, first, boost::mpl::back_inserter<boost::mpl::vector<mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na> > >' requested here typedef boost::mpl::transform<fusion_sequence1_type, ^ c++/4.8.0/tuple:672:12: note: template is declared here struct tuple_element; ^ 1 error generated. Seems like something is trying to call value_of on the begin iterator of the tuple, which in the case of an empty tuple is a past-the-end iterator. If I use non-empty tuples instead: typedef std::tuple<int> fusion_sequence1_type; typedef std::tuple<int> fusion_sequence2_type; It works fine. Unary mpl::transform works fine in either case. Am I doing something wrong, or is this a bug? Thanks, Nate
participants (1)
-
Nathan Ridge