
On Mar 8, 2004, at 11:40 AM, Gabriel Dos Reis wrote:
Jaakko Jarvi <jajarvi@cs.indiana.edu> writes:
| On Sun, 8 Mar 2004, Gabriel Dos Reis wrote: | | > Jaakko Jarvi <jajarvi@cs.indiana.edu> 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@cs.indiana.edu -- Post Doctoral Fellow phone: +1 (812) 855-3608 -- Pervasive Technology Labs fax: +1 (812) 855-4829 -- Indiana University, Bloomington