Boost logo

Boost :

Subject: Re: [boost] [MPL] Bug with default lambda expressions?
From: Larry Evans (cppljevans_at_[hidden])
Date: 2013-05-22 09:09:08


On 05/22/13 07:16, Larry Evans wrote:
> On 05/21/13 18:04, Larry Evans wrote:
>> On 05/21/13 15:43, Louis Dionne wrote:
>>> Hi,
>>>
>>> Some higher order algorithms in the MPL have a default for the lambda
>>> expression they accept. A good example is `boost::mpl::equal`:
>>>
>>> template <typename S1, typename S2, typename Pred = is_same<_, _> >
>>> struct equal;
>>>
>>> This works fine most of the time, but I was recently bitten by the following:
>>>
>>> template <typename VectorOfVectors, typename Vector>
>>> struct find_vector
>>> : find_if<
>>> VectorOfVectors, equal<Vector, _1>
>>> >
>>> { };
>>>
>>> typedef find_vector<
>>> vector<
>>> vector<int, int>,
>>> vector<char, char>
>>> >,
>>> vector<char, char>
>>> >::type ThisWillBreak;
>>>
>>> What happens here is that the `equal<Vector, _1>` expression inside
>>> `find_vector` really is `equal<Vector, _1, is_same<_1, _2> >` because
>>> of the default value for the predicate to `equal`. When the lambda is
>>> evaluated, the placholders inside the inner `is_same<_1, _2>` expression
>>> are replaced too, which yields unexpected results.
>>>
>>> Using
>>>
>>> template <typename S1, typename S2,
>>> typename Pred = typename lambda<is_same<_, _> >::type>
>>> struct equal;
>>>
>>> or equivalently
>>>
>>> template <typename S1, typename S2, typename Pred = quote2<is_same> >
>>> struct equal;
>>>
>>> fixes the issue. Also note that all of the unit tests of the MPL still pass
>>> with these changes. Is the current behavior intended, or should I submit
>>> a patch?
>>>
>>>
>>> Regards,
>>>
>>> Louis Dionne
>>>
>> This sounds like a problem similar to the one here:
>>
>> http://article.gmane.org/gmane.comp.lib.boost.devel/227344
>>
>> Maybe reading that thread would give you some ideas for
>> a solution.
>>
> OOPS. I should have read further and noted your solution using lambda.
> Sorry for noise.
>
> However, with the attached and your changes and gcc4.8 I'm getting
> errors:
>
> bug_with_default_lambda.cpp:18:12: required from 'struct
> find_vector<boost::mpl::vector<boost::mpl::vector<int, int>,
> boost::mpl::vector<char, char> >, boost::mpl::vector<char, char> >'
> bug_with_default_lambda.cpp:30:6: required from here
> /home/evansl/prog_dev/boost-svn/ro/boost_1_53_0/boost/mpl/aux_/preprocessed/gcc/apply_wrap.hpp:36:8:
> error: no class template named 'apply' in 'struct
> boost::mpl::equal<boost::mpl::vector<char, char>, mpl_::arg<1>,
> boost::mpl::protect<boost::mpl::bind2<boost::mpl::quote2<boost::is_same,
> mpl_::void_>, mpl_::arg<-1>, mpl_::arg<-1> >, 0> >'
> struct apply_wrap1
> ^
> In file included from
> /home/evansl/prog_dev/boost-svn/ro/boost_1_53_0/boost/mpl/not.hpp:19:0,
> from
> /home/evansl/prog_dev/boost-svn/ro/boost_1_53_0/boost/mpl/assert.hpp:17,
> from
> /home/evansl/prog_dev/boost-svn/ro/boost_1_53_0/boost/mpl/aux_/na_assert.hpp:23,
> from
> /home/evansl/prog_dev/boost-svn/ro/boost_1_53_0/boost/mpl/arg.hpp:25,
> from
> /home/evansl/prog_dev/boost-svn/ro/boost_1_53_0/boost/mpl/placeholders.hpp:24,
> from
> /home/evansl/prog_dev/boost-svn/ro/boost_1_53_0/boost/mpl/apply.hpp:24,
> from
> /home/evansl/prog_dev/boost-svn/ro/boost_1_53_0/boost/mpl/aux_/iter_fold_if_impl.hpp:22,
> from
> /home/evansl/prog_dev/boost-svn/ro/boost_1_53_0/boost/mpl/equal.hpp:17,
> from bug_with_default_lambda.cpp:10:
> .
> .
> .
>
> The mpl/equal.hpp contains your suggested modification:
>
> template<
> typename BOOST_MPL_AUX_NA_PARAM(Sequence1)
> , typename BOOST_MPL_AUX_NA_PARAM(Sequence2)
> #ifdef LJE_USE_LAMBDA_PREDICATE_IS_SAME
> , typename Predicate = typename lambda<is_same<_,_> >::type
> #else
> , typename Predicate = is_same<_,_>
> #endif
> >
> struct equal
> : aux::msvc_eti_base<
> typename aux::equal_impl<Sequence1,Sequence2,Predicate>::type
> >::type
> {
> BOOST_MPL_AUX_LAMBDA_SUPPORT(2,equal,(Sequence1,Sequence2))
> };
>
>
> Could you supply a complete test case so I can see what I might
> be doing wrong to reproduce your solution?
>
> TIA.
>
> -regards,
> Larry

Strangely enough, when the changes to mpl/equal.hpp were backed out,
and the lambda was put in test driver, as shown in attached, it
compiles OK.

-Larry




Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk