Boost logo

Boost :

Subject: [boost] [mpl] Nested Scopes w/Placeholders
From: Kitten, Nicholas (nkitten_at_[hidden])
Date: 2012-01-13 20:44:07


I've recently been doing a lot mpl::folding (in boost 1.47), and I was
disappointed when I realized that a nested fold wouldn't work with a lambda
expression passed to the inner call, as in this example which extracts
elements of sequences:

  using namespace mpl;
  using namespace mpl::placeholders;

  typedef vector< vector<char>, vector<int> > vec_of_vecs;
  typedef vector< char, int > expected_result;

  typedef fold< vec_of_vecs,
                      vector<>,
                      fold< _2,
                              _1,
                              *push_back< _1, _2 >* // wrong - refers to
outer arguments
>
>::type result;

  BOOST_MPL_ASSERT(( equal<result, expected_result> ));

After looking around for a solution I came across an old
thread<http://lists.boost.org/boost-users/2004/12/9269.php> on
the same subject, where it was suggested using mpl::protect might work.
 Indeed, the following modification does what I want, without any changes
to the library:

  typedef fold< vec_of_vecs,
                      vector<>,
                      fold< _2,
                              _1,
                              *protect< lambda< push_back< _1, _2 > >::type
>* // correct
>
>::type result;

Of course, this is a little on the verbose side. In the old thread, Daniel
Wallin suggested suggested changing the definition of lambda to yield
syntax more in line with the runtime version of boost::bind, but that would
apparently break other code. What about instead adding a specialization to
protect for placeholder expressions? Indeed, the source in protect.hpp
seems to indicate such a thing might've been in the works at one point, but
I didn't see any more references to it:

template<
      typename BOOST_MPL_AUX_NA_PARAM(T)
* , int not_le_ = 0 // not lambda expression?*
>
struct protect : T
{
...
typedef protect type;
};

What about changing it to something like this?

template<
      typename BOOST_MPL_AUX_NA_PARAM(T)
* , typename not_le_ = typename is_lambda_expression< T >::type*
>
struct protect : T
{
...
typedef protect type;
};

*template< typename T >*
*struct protect< T, mpl::true_ > : lambda<T>*
*{*
*...*
*typedef protect type;*
*};*

Doing so would remove the inner lambda<...>::type expression, yielding the
expected syntax. Could that be done without messing up everything else?

Thanks,

*Nick Kitten*

Software Engineer
Center for Video Understanding Excellence

ObjectVideo, Inc.


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