I wonder how people are using C++0x lambdas, in terms of coding style. The most interesting question is how thorough to be when writing the capture list. On one hand, the language allows to list captured variables explicitly, and by the "explicit is better than implicit rule", it would therefore make sense to do an exhaustive listing to clearly state the intetion. E.g.:
int sum;
std::for_each(xs.begin(), xs.end(), [&sum](int x) { sum += x });
Another argument for this is that, since lifetime of ref-captured locals doesn't change just because they're captured (and so a lambda can easily end up referencing a local whose lifetime has long ended), making capture explicit helps reduce such bugs and track them down.
On the other hand, the language also deliberately provides a shortcut for auto-capturing all referenced locals, so clearly it's intended to be used. And one could claim that for an example such as one above, it is very clear what happens even with auto-capture, and lifetime of lambda is such that it won't outlive the surrounding scope, so there's no reason not to use it:
int sum;
std::for_each(xs.begin(), xs.end(), [&](int x) { sum += x });
Obviously this doesn't have to be all-or-nothing, but there has to be some rationale to decide when to auto-capture, and when to do capture explicitly. Any thoughts?
Another question in the same vein is when to use capture-by-copy - [=]
, and when to use capture-by-reference - [&]
. Capture-by-copy is obviously safer because there are no lifetime issues, so one could argue that it should be used by default whenever there's no need to mutate the captured value (or see the changes done to it from elsewhere), and capture-by-reference should be treated as (potentially premature) optimization in such cases, to be applied only where it clearly makes a difference.
On the other hand, capture-by-reference is almost always faster (especially as it can often be optimized down to a copy, if the latter is actually faster, for small types and inlineable template functions such as most STL algorithms), and is safe if lambda never outlives its scope (which is also the case for all STL algorithms), so defaulting to capture-by-reference in this case is a trivial and harmless optimization which doesn't hurt.
What are your thoughts?