On Monday, February 01, 2016 11:08:54 AM Marc Mutz wrote: > Hi, > > We're seeing increasing use of lambdas in dev, and I'm a bit unhappy about > the result. > > E.g. (not picking on Anton here, I have done the same before): > > auto firstEqualsName = [&name](const QPair<QByteArray, QByteArray> &header) > { > return qstricmp(name.constData(), header.first) == 0; > }; > fields.erase(std::remove_if(fields.begin(), fields.end(), > firstEqualsName), > fields.end()); > > This is one way to write a unary predicate. But it hides the fact that the > predicate depends on the parameter 'name' (an argument to the function this > lambda is defined in). > > With classical function objects, one would have written - at the call site: > > fields.erase(std::remove_if(fields.begin(), fields.end(), > FirstEquals(name)), > fields.end()); > > See the difference? > > Now, we don't want to go back and write function objects for one-time use, > but it would be nice to have this explicit syntax, would it not? > > One way to have this with lambdas is to write a lambda that returns a > lambda. We can do this, because auto return type deduction works for > lambdas already in C++11, unlike for normal functions. With this, the above > would become (hold tight): > > auto firstEquals = [](const auto &name) { > return [&name](auto header) { return qstricmp(header.first, name) == 0; > }; } > > where I used auto and dropped the const-& argument passing only for > exposition, to get it onto a single line. > > fields.erase(std::remove_if(fields.begin(), fields.end(), > firstEquals(name)), > fields.end()); > > So, where to put the ugliness: on the definition of the lambda, or the call > site? (Note that "if you use this lambda more than once, then X" is not a > good answer, because you shouldn't use lambdas more than once. But with the > lambda- returning-lambda, you could actually reuse them: > > // at global scope: > > auto firstEquals = [](const auto &name) { > return [&name](auto header) { return qstricmp(header.first, name) == 0; > }; } > > // use in several functions - always the same type > > Whereas without the outer lambda, each use would create a new type, and > potentially duplicate code (same problem as QStringLiteral, and the same > soultion, really: wrap them in a function, except for lambdas, because of > the unnameable return type, we need to use another lambda instead of a > classical function).
I would write: removeIfFirstEquals(fields, name): because: 1) I could read it in English instead of very verbose C++ 2) I would not need to read the implementation And for the implementation.. it doesn't matter, it's a named function, only does one small thing and does it good. About the inlining, which compilers don't and does it make a difference ? A function call should negligible compared to erase + remove_if Regards, -- Sérgio Martins | sergio.mart...@kdab.com | Software Engineer Klarälvdalens Datakonsult AB, a KDAB Group company Tel: Sweden (HQ) +46-563-540090, USA +1-866-777-KDAB(5322) KDAB - The Qt Experts _______________________________________________ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development