Boost logo

Boost :

From: Jaakko Jarvi (jajarvi_at_[hidden])
Date: 2004-03-08 16:04:25


On Mar 8, 2004, at 11:40 AM, Gabriel Dos Reis wrote:

> Jaakko Jarvi <jajarvi_at_[hidden]> writes:
>
> | On Sun, 8 Mar 2004, Gabriel Dos Reis wrote:
> |
> | > Jaakko Jarvi <jajarvi_at_[hidden]> writes:
> | >
> |
> | Right, variables with local storage cannot be used in local classes.
> | Now this rule would forbid the above (which is good), but it would
> also
> | rule out useful and safe lambdas:
>
> Those who are considered safe would have markers sayign they are safe
> to export, or they would have markers saying only their values are
> needed.
>
> |
> | auto foo(int x, int y) {
> | int i = x+y; // just some computation to motivate a local
> variable
> | vector<int> v;
> | ...
> | transform(v.begin(), v.end(), v.begin(),
> | auto(int x) { return x+i; });
>
> Hmm, I do not see the difference between the "i" here and the "i"
> above. They are both automatic.
>
> But, if you want to tell the compiler that it is OK to use the value
> of a local variable then use lambda lifting, e.g.
>
> transform(v.begin(), v.vend(), v.begin()
> (auto x) ((int y) auto { return y + x; }) (i));
>

Yes, but this is a quite complex and hard to read way to express
something simpler.
And it seems that in the inner lambda, x would be a variable from an
outer scope
with automatic storage, just like i is, and would therefore have to be
rejected
by the current local class rules.

<snip corresponding function object classes>

Yes, I think all the building blocks are there, function object classes
can be used as the implementation for lambdas, but the rules of
referring to
automatic storage variables would need to be more permissive than the
ones
of local classes.

>
> | Which you can currently write using BLL as:
> |
> | transform(v.begin(), v.end(), v.begin(), _1 + i);
> |
> | (BLL stores a copy to i internally)
>
> what about
>
> struct stream {
> // ...
> int send(message);
> private:
> stream(const stream&); // not implemented, prevent
> copy
> stream& operator=(const stream&); // ditto;
> };
>
>
> stream out("127.0.0.1:6001");
> // ...
> for_each(v.begin(), v.end(), out.send(message(_1)));
>
> ? Does it copy out?
>

One would have to write this as:

   for_each(v.begin(), v.end(), bind(&stream::send, ref(out), _1));

The important point is 'ref', which instructs to store a reference, not
a copy.
The default is 'store a copy' (except for in some contexts, such as on
the left
of += operator).

   Cheers, Jaakko

> The usual pass-by-value semantics would be still possible, modulo
> explicit annotation. Plus, you would have the choice to say explicitly
> const ref vs. plain copy vs. plain ref.
>
> In the simple-minded model I discussed, the above would be
>
> stream out(127.0.0.1:6001");
> // ...
> for_each(v.begin(), v.end(),
> (stream& s) ((int x) { s.send(x); }) (out));
>
> -- Gaby
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>
-- Jaakko Järvi email:
jajarvi_at_[hidden]
-- Post Doctoral Fellow phone: +1 (812) 855-3608
-- Pervasive Technology Labs fax: +1 (812) 855-4829
-- Indiana University, Bloomington


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