> >> I have a fairly large program that compiled just fine on boost_trunk > >> version 67416, but is now broken. I traced to problem to an > >> ambiguous operator overload that occurs when both qi.hpp and > >> fusion/tuple.hpp are included. > >> > >> The following code does not compile as of today, but should compile > >> on version 67416. > >> > >> #include <boost/fusion/tuple.hpp> //including this file caused > >> ambiguity errors #include <boost/spirit/include/qi.hpp> #include > >> <string> > >> > >> int main() > >> { > >> static const boost::spirit::qi::rule<std::string::const_iterator> a; > >> static const boost::spirit::qi::rule<std::string::const_iterator> b; > >> boost::spirit::qi::rule<std::string::const_iterator> rule = a > b; > >> } > >> > > > > Ohh, that looks serious! The ambiguity is caused by a proto/fusion > overlap. > > A qi::rule is both, a proto expression and a fusion sequence (as all > > proto expressions are proto sequences now). > > > > Proto's overload for operator>() is a valid choice for this, as is > > fusions > > operator>(). > > > > I'm cc'ing Eric and Christopher, perhaps they have an idea how to > proceed. > > I suggest defining a Fusion trait, is_less_then_comparable, and define it > for the built-in Fusion sequences (tuple, vector, etc.). That can be used > to SFINAE out Fusion's operator<, which should not be picked up for Proto > expressions. Ditto for the other operations on Fusion sequences. > > I have no better ideas at the moment.
Fusion already has a traits class for this, but it's not SFINAE enabled (see boost/fusion/sequence/comparison/detail/enable_comparison.hpp), even if it's in 'namespace detail'. Adding an additional template parameter to make it into a customization point: namespace boost { namespace fusion { namespace detail { template <typename Seq1, typename Seq2, typename Enable = void> struct enable_equality ... template <typename Seq1, typename Seq2, typename Enable = void> struct enable_comparison ... }}} which allows to add: namespace boost { namespace fusion { namespace detail { template <typename T1, typename T2> struct enable_equality<T1, T2, typename enable_if<mpl::or_<proto::is_expr<T1>, proto::is_expr<T2> > >::type> : mpl::false_ {}; template <typename T1, typename T2> struct enable_comparison<T1, T2, typename enable_if<mpl::or_<proto::is_expr<T1>, proto::is_expr<T2> > >::type> : mpl::false_ {}; }}} I'm currently running the Fusion tests to see whether the additional 'typename Enable = void' break anything. But I expect everything to work - Yep everything is fine. Eric, would you be willing to add the specializations above to Proto's Fusion adaptation code? Regards Hartmut --------------- http://boost-spirit.com _______________________________________________ proto mailing list proto@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/proto