|
Boost : |
Subject: Re: [boost] [mpl] Nested Scopes w/Placeholders
From: Aleksey Gurtovoy (agurtovoy_at_[hidden])
Date: 2012-02-06 03:16:41
On Thu, 26 Jan 2012 09:09:36 -0600, Kitten, Nicholas
<nkitten_at_[hidden]> wrote:
> On Mon, Jan 23, 2012 at 2:30 AM, Aleksey Gurtovoy
> <agurtovoy_at_[hidden]> wrote:
>> Personally, I'd rather work on a more general scoping mechanism
>> along the lines of
>> http://article.gmane.org/gmane.comp.lib.boost.devel/116000
>
> Alright, that seems reasonable, so I'll share my thoughts. Looking at
> the options, if you're concerned about backwards compatibility,
> then it seems like any kind of implicit local scoping (for library
> algorithms or lambda expressions) is out. That leaves explicit
> scopes used with either local variable declarations (Phoenix's let[]
> solution) or something similar to the outer() syntax you suggested:
>
>> // outer(arg1)
>> template< int n >
>> outer_argument<1,n> outer(arg<n>);
>>
>> // outer(... outer(arg1))
>> template< int scope, int n >
>> outer_argument<scope+1,n> outer(outer_argument<scope,n>);
>>
>> // outer<n>(arg1)
>> template< int scope, int n >
>> outer_argument<scope,n> outer(arg<n>);
>
> Okay, let's see what syntax might look like for both options. First,
> using Phoenix's simple use case:
>
> write a lambda expression that accepts:
>
> 1. a 2-dimensional container (e.g. vector<vector<int> >)
> 2. a container element (e.g. int)
>
> and pushes-back the element to each of the vector<int>.
>
> Here's my take on it:
>
> typedef vector< vector<char>, vector<char> > vec_of_vecs;
> typedef vector< vector<char,int>, vector<char,int> > expected_result;
>
> // scope and outer version
> typedef transform< _1,
> scope<
> push_back< _1, outer< _2 > >
> >
> > lambda_e1;
>
> // let<> version, with let declared as:
> // template< LetExpression, typename a = _1, typename b = _2, ... >
> struct let; <--- LetExpression includes _a, _b, etc.
> typedef transform< _1,
> let<
> push_back< _1, _a >,
> _2 // <-- declares _a to be outer _2
> >
> > lambda_e2;
>
> BOOST_MPL_ASSERT(( equal< apply2< lambda_e1, vec_of_vecs, int
>> ::type, expected_result, equal<_1, _2> > ));
> BOOST_MPL_ASSERT(( equal< apply2< lambda_e2, vec_of_vecs, int
>> ::type, expected_result, equal<_1, _2> > ));
>
> Here, let<>, like bind<>, reduces readability somewhat as you have to
> look after the expression for declarations, so I think the outer<>
> form would be the better of the two for MPL.
That's my current preference as well. Now all we need is for somebody to
implement this :).
-- Aleksey Gurtovoy MetaCommunications Engineering
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk