Opened 10 years ago

Closed 10 years ago

#7503 closed Bugs (fixed)

for_each does not compile with g++-4.7.1

Reported by: veso <vveesskkoo@…> Owned by: Joel de Guzman
Milestone: Boost 1.52.0 Component: fusion
Version: Boost 1.51.0 Severity: Problem
Keywords: Cc:

Description

Hello,

The following code works fine with g++-4.4 and can not compile with g++-4.7.1.

#include <iostream> #include <string> #include <type_traits> #include <typeinfo>

#include <boost/fusion/include/map.hpp> #include <boost/fusion/include/filter_if.hpp> #include <boost/fusion/include/for_each.hpp>

namespace fusion = boost::fusion;

template<typename Key_Base_T, typename Pair_T> struct is_same_key: public std::is_same<Key_Base_T, typename Pair_T::first_type> {};

struct print_ftor {

template<typename Key_T, typename Value_T> inline void operator()(const boost::fusion::pair<Key_T, Value_T>& pair) const {

std::cout << "type: " << typeid(Key_T).name() << ", value: " << pair.second << std::endl;

}

};

int main () {

typedef fusion::map< fusion::pair<int, char>,

fusion::pair<double, std::string> >

map_type;

map_type map_sequence( fusion::make_pair<int>('X'),

fusion::make_pair<double>("Men") );

fusion::for_each( fusion::filter_if< is_same_key< double, boost::mpl::_1> >(map_sequence),

print_ftor());

return 0;

}

The error which the compiler produces is:

g++-4.7 -o test -std=c++0x -Wall -pedantic -I/home/veso/boost_1_52_0_beta1 main.c++ main.c++: In instantiation of ‘struct is_same_key<double, mpl_::arg<1> >’: /home/veso/boost_1_52_0_beta1/boost/fusion/algorithm/iteration/detail/for_each.hpp:32:9: required from ‘void boost::fusion::detail::for_each_linear(const First&, const Last&, const F&, mpl_::false_) [with First = boost::fusion::filter_iterator<boost::mpl::inherit2<boost::fusion::forward_traversal_tag, boost::fusion::associative_tag>, boost::fusion::basic_iterator<boost::fusion::map_iterator_tag, boost::fusion::map<boost::fusion::pair<int, char>, boost::fusion::pair<double, std::basic_string<char> > >::category, const boost::fusion::map<boost::fusion::pair<int, char>, boost::fusion::pair<double, std::basic_string<char> > >, 0>, boost::fusion::basic_iterator<boost::fusion::map_iterator_tag, boost::fusion::map<boost::fusion::pair<int, char>, boost::fusion::pair<double, std::basic_string<char> > >::category, const boost::fusion::map<boost::fusion::pair<int, char>, boost::fusion::pair<double, std::basic_string<char> > >, 2>, is_same_key<double, mpl_::arg<1> > >; Last = boost::fusion::filter_iterator<boost::mpl::inherit2<boost::fusion::forward_traversal_tag, boost::fusion::associative_tag>, boost::fusion::basic_iterator<boost::fusion::map_iterator_tag, boost::fusion::map<boost::fusion::pair<int, char>, boost::fusion::pair<double, std::basic_string<char> > >::category, const boost::fusion::map<boost::fusion::pair<int, char>, boost::fusion::pair<double, std::basic_string<char> > >, 2>, boost::fusion::basic_iterator<boost::fusion::map_iterator_tag, boost::fusion::map<boost::fusion::pair<int, char>, boost::fusion::pair<double, std::basic_string<char> > >::category, const boost::fusion::map<boost::fusion::pair<int, char>, boost::fusion::pair<double, std::basic_string<char> > >, 2>, is_same_key<double, mpl_::arg<1> > >; F = print_ftor; mpl_::false_ = mpl_::bool_<false>]’ /home/veso/boost_1_52_0_beta1/boost/fusion/algorithm/iteration/detail/for_each.hpp:42:9: required from ‘void boost::fusion::detail::for_each_dispatch(Sequence&, const F&, Tag) [with Sequence = const boost::fusion::filter_view<const boost::fusion::map<boost::fusion::pair<int, char>, boost::fusion::pair<double, std::basic_string<char> > >, is_same_key<double, mpl_::arg<1> > >; F = print_ftor; Tag = boost::mpl::inherit2<boost::fusion::forward_traversal_tag, boost::fusion::associative_tag>]’ /home/veso/boost_1_52_0_beta1/boost/fusion/algorithm/iteration/detail/for_each.hpp:132:9: required from ‘void boost::fusion::detail::for_each(Sequence&, const F&, mpl_::false_) [with Sequence = const boost::fusion::filter_view<const boost::fusion::map<boost::fusion::pair<int, char>, boost::fusion::pair<double, std::basic_string<char> > >, is_same_key<double, mpl_::arg<1> > >; F = print_ftor; mpl_::false_ = mpl_::bool_<false>]’ /home/veso/boost_1_52_0_beta1/boost/fusion/algorithm/iteration/for_each.hpp:49:9: required from ‘typename boost::enable_if<boost::fusion::traits::is_sequence<Sequence>, void>::type boost::fusion::for_each(const Sequence&, const F&) [with Sequence = boost::fusion::filter_view<const boost::fusion::map<boost::fusion::pair<int, char>, boost::fusion::pair<double, std::basic_string<char> > >, is_same_key<double, mpl_::arg<1> > >; F = print_ftor; typename boost::enable_if<boost::fusion::traits::is_sequence<Sequence>, void>::type = void]’ main.c++:33:19: required from here main.c++:13:8: error: no type named ‘first_type’ in ‘struct mpl_::arg<1>’ make: * [all] Error 1

For the test I used Debian stable with g++-4.7 installed from the backport repository.

The bug appears with boost versions 1.42, 1.51, 1.51beta1

Attachments (1)

g4.7bug.zip (799 bytes ) - added by veso <vveesskkoo@…> 10 years ago.

Download all attachments as: .zip

Change History (2)

by veso <vveesskkoo@…>, 10 years ago

Attachment: g4.7bug.zip added

comment:1 by Joel de Guzman, 10 years ago

Resolution: fixed
Status: newclosed

Better wrap your expression in an mpl::lambda to avoid eager evaluation (typename Pair_T::first_type). Here's how you do it:

typedef is_same_key< double, boost::mpl::_1> expr; typedef boost::mpl::lambda<expr>::type func; fusion::for_each( fusion::filter_if<func>(map_sequence), print_ftor());

See http://www.mywikinet.com/mpl/paper/html/lambda.html for details.

Note: See TracTickets for help on using tickets.