On 11/02/14 16:38, Gerhard Raven wrote:
Hi Wilco,
in this example, I’m certainly not going to argue against you ;-)
But if you start ‘lifting’ (i.e. factor out implentation details, and writing fully generic code) then one ‘has’ to remove the ‘detail' of what the predicate actually does and ‘package’ it into some functor which is passed into the generic code — in general, I’d like to see some ‘higher level iterators’, along the lines of http://www.boost.org/doc/libs/1_55_0/libs/range/doc/html/range/reference/ada... in which case one can separate the ‘looping over the good bits of stuff only’ from the ‘do something with the individual items of good stuff’. Extrapolating from this example, the predicate shouldn’t even appear in the loop body, but in the loop-control part. That way one can ‘compose’ various predicates, and also various loop bodies. Concrete example: there is no ‘std::transform_if’ — but if uses the boost range adaptors, then there is no need for one, as the ‘if’ bit is pushed into the iterators ;-)
Most of this can be done with inline functions, though lambda functions are particularly useful for as arguments for maps, sorts, filters, or other functions which require a predicate.
So in that sense, it is good that the compilers we have are good enough that a lambda has no overhead ;-) Also, in case the lambda becomes more than a few lines of code, or is used in several locations, then it makes sense to code a dedicated struct with an operator() and give it a name — just the fact that it has a name serves as documentation…
Sure, but if you start naming your lambda/anonymous functions and reusing them in multiple functions, they are no longer anonymous and might as well use an inline function, which has the same net effect.
-- Wilco