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>*);
                            ^