|
Boost : |
Subject: Re: [boost] [MPL] Bug with default lambda expressions?
From: Larry Evans (cppljevans_at_[hidden])
Date: 2013-05-22 08:16:52
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
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk