|
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