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 >
struct equal;
This works fine most of the time, but I was recently bitten by the following:
template
struct find_vector
: find_if<
VectorOfVectors, equal
>
{ };
typedef find_vector<
vector<
vector,
vector
>,
vector
>::type ThisWillBreak;
What happens here is that the `equal` expression inside
`find_vector` really is `equal >` 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 >::type>
struct equal;
or equivalently
template >
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 >'
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, mpl_::arg<1>,
boost::mpl::protect, 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 >::type
#else
, typename Predicate = is_same<_,_>
#endif
>
struct equal
: aux::msvc_eti_base<
typename aux::equal_impl::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