[fusion] [mpl] binary MPL transform on empty fusion vectors

Hi, I've run into an error in code involving MPL and Fusion which I've reduced to the following: #include <boost/mpl/transform.hpp> #include <boost/fusion/container/vector.hpp> #include <boost/fusion/mpl.hpp> struct predicate { template <typename T, typename U> struct apply { typedef T type; }; }; typedef boost::mpl::transform< boost::fusion::vector<>, boost::fusion::vector<>, predicate> ::type Result; This simple piece of code tries to perform a binary MPL transform on two fusion vectors of size 0. It produces the error reproduced below, with both gcc 5.1 and clang 3.7. My boost version is 1.60. I'm quite sure that this used to work with an older boost and compiler version combination, though I don't recall which exactly (something in the vicinity of boost 1.54 / gcc 4.8). Did I run into a regression, or should I not be expecting this to work in the first place? Should I be special-casing zero-length vectors? Thanks, Nate In file included from test.cpp:2: In file included from boost/include/boost/fusion/container/vector.hpp:12: In file included from boost/include/boost/fusion/container/vector/vector.hpp:28: In file included from boost/include/boost/fusion/container/vector/detail/at_impl.hpp:12: boost/include/boost/fusion/container/vector/detail/value_at_impl.hpp:50:57: error: no matching function for call to 'value_at_impl' typedef typename mpl::identity<decltype(seq::template value_at_impl<N::value>(boost::declval<seq*>()))>::type::type type; ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ boost/include/boost/fusion/container/vector/detail/value_of_impl.hpp:30:61: note: in instantiation of template class 'boost::fusion::extension::value_at_impl<boost::fusion::vector_tag>::apply<boost::fusion::vector<>, mpl_::int_<0>>' requested here typedef typename value_at_impl<vector_tag>::template apply<vector, index>::type type; ^ boost/include/boost/fusion/iterator/value_of.hpp:52:15: note: in instantiation of template class 'boost::fusion::extension::value_of_impl<boost::fusion::vector_iterator_tag>::apply<boost::fusion::vector_iterator<boost::fusion::vector<>, 0>>' requested here : extension::value_of_impl<typename detail::tag_of<Iterator>::type>:: ^ boost/include/boost/fusion/iterator/mpl/fusion_iterator.hpp:47:45: note: in instantiation of template class 'boost::fusion::result_of::value_of<boost::fusion::vector_iterator<boost::fusion::vector<>, 0>>' requested here typedef typename fusion::result_of::value_of<Iterator>::type type; ^ boost/include/boost/mpl/iterator_category.hpp:27:22: note: in instantiation of template class 'boost::mpl::fusion_iterator<boost::fusion::vector_iterator<boost::fusion::vector<>, 0>>' requested here typedef typename Iterator::category type; ^ boost/include/boost/mpl/pair_view.hpp:152:20: note: in instantiation of template class 'boost::mpl::iterator_category<boost::mpl::fusion_iterator<boost::fusion::vector_iterator<boost::fusion::vector<>, 0>>>' requested here typename iterator_category<iter1_>::type ^ boost/include/boost/mpl/aux_/has_tag.hpp:20:1: note: in instantiation of template class 'boost::mpl::pair_view<boost::fusion::vector<>, boost::fusion::vector<>>' requested here BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_tag, tag, false) ^ boost/include/boost/mpl/has_xxx.hpp:245:65: note: expanded from macro 'BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF' , boost::mpl::aux::type_wrapper<BOOST_MSVC_TYPENAME U::name>* = 0 \ ^ boost/include/boost/mpl/aux_/has_tag.hpp:20:1: note: while substituting deduced template arguments into function template 'test' [with U = boost::mpl::pair_view<boost::fusion::vector<>, boost::fusion::vector<>>] BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_tag, tag, false) ^ boost/include/boost/mpl/has_xxx.hpp:253:18: note: expanded from macro 'BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF' sizeof(gcc_3_2_wknd::test(static_cast<t_*>(0))) \ ^ boost/include/boost/config/suffix.hpp:394:72: note: expanded from macro 'BOOST_STATIC_CONSTANT' # define BOOST_STATIC_CONSTANT(type, assignment) static const type assignment ^ boost/include/boost/mpl/sequence_tag.hpp:112:30: note: in instantiation of template class 'boost::mpl::aux::has_tag<boost::mpl::pair_view<boost::fusion::vector<>, boost::fusion::vector<>>, mpl_::bool_<false>>' requested here ::boost::mpl::aux::has_tag<Sequence>::value ^ boost/include/boost/mpl/O1_size.hpp:30:30: note: in instantiation of template class 'boost::mpl::sequence_tag<boost::mpl::pair_view<boost::fusion::vector<>, boost::fusion::vector<>>>' requested here : O1_size_impl< typename sequence_tag<Sequence>::type> ^ boost/include/boost/mpl/fold.hpp:34:25: note: in instantiation of template class 'boost::mpl::O1_size<boost::mpl::pair_view<boost::fusion::vector<>, boost::fusion::vector<>>>' requested here ::boost::mpl::O1_size<Sequence>::value ^ boost/include/boost/mpl/transform.hpp:75:7: note: in instantiation of template class 'boost::mpl::fold<boost::mpl::pair_view<boost::fusion::vector<>, boost::fusion::vector<>>, boost::fusion::vector<>, boost::mpl::bind2<boost::mpl::push_back<mpl_::na, mpl_::na>, mpl_::arg<1>, boost::mpl::bind2<predicate, 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/include/boost/mpl/transform.hpp:114:1: note: in instantiation of template class 'boost::mpl::aux::transform2_impl<boost::fusion::vector<>, boost::fusion::vector<>, predicate, boost::mpl::back_inserter<boost::fusion::vector<>>>' requested here BOOST_MPL_AUX_INSERTER_ALGORITHM_DEF(4, transform2) ^ boost/include/boost/mpl/aux_/inserter_algorithm.hpp:52:7: note: expanded from macro 'BOOST_MPL_AUX_INSERTER_ALGORITHM_DEF' : if_< has_push_back< typename clear<P1>::type> \ ^ boost/include/boost/mpl/eval_if.hpp:38:22: note: in instantiation of template class 'boost::mpl::transform2<boost::fusion::vector<>, boost::fusion::vector<>, predicate, mpl_::na>' requested here typedef typename f_::type type; ^ boost/include/boost/mpl/transform.hpp:138:1: note: in instantiation of template class 'boost::mpl::eval_if<boost::mpl::or_<boost::mpl::is_na<predicate>, boost::mpl::is_lambda_expression<boost::fusion::vector<>>, boost::mpl::not_<boost::mpl::is_sequence<boost::fusion::vector<>>>, mpl_::bool_<false>, mpl_::bool_<false>>, boost::mpl::transform1<boost::fusion::vector<>, boost::fusion::vector<>, predicate>, boost::mpl::transform2<boost::fusion::vector<>, boost::fusion::vector<>, predicate, mpl_::na>>' requested here AUX778076_TRANSFORM_DEF(transform) ^ boost/include/boost/mpl/transform.hpp:125:22: note: expanded from macro 'AUX778076_TRANSFORM_DEF' typedef typename eval_if< \ ^ test.cpp:13:17: note: in instantiation of template class 'boost::mpl::transform<boost::fusion::vector<>, boost::fusion::vector<>, predicate, mpl_::na>' requested here boost::mpl::transform< ^ boost/include/boost/fusion/container/vector/vector.hpp:275:30: note: candidate template ignored: could not match 'store' against 'vector' mpl::identity<U> value_at_impl(store<N, U>*); ^

Hi Nathan, On 2016/01/20 14:02, Nathan Ridge wrote:
This simple piece of code tries to perform a binary MPL transform on two fusion vectors of size 0. It produces the error reproduced below, with both gcc 5.1 and clang 3.7. My boost version is 1.60. It seems a regression, from 1.60.0 w/ C++11(or later) mode. Could you file that to https://svn.boost.org/trac/boost/ ?
Best, Kohei Takahashi

It seems a regression, from 1.60.0 w/ C++11(or later) mode. Could you file that to https://svn.boost.org/trac/boost/ ?
Thanks, I have filed https://svn.boost.org/trac/boost/ticket/11932. Regards, Nate
participants (2)
-
Kohei Takahashi
-
Nathan Ridge