News:

Help! We're trapped in the computer, and the computer is trapped in 2008! Someone call the time police!

Main Menu

Lambdas and 'auto' types in C++11

Started by nslay, January 07, 2014, 11:37:10 PM

Previous topic - Next topic

0 Members and 2 Guests are viewing this topic.

nslay

Does anyone really think lambda expressions help C++? I think it's nice to be able to create functors on the fly, although it's not always readable.

STL has <algorithm> which includes algorithms like std::for_each and std::find_if that accept functors/functions. In the past you usually had to create a functor to use these which was typically more code than just writing your own for loop. I thought lambdas would make functions like std::for_each practical. However, which is more readable?


int sum = 0;
std::vector<int> vArray = { 1, 2, 3, 4, 5 }; // Yes, you can do this in C++11
std::for_each(std::begin(vArray), std::end(vArray), [&sum](int x) {
  sum += 2*x;
});


Or


int sum = 0;
std::vector<int> vArray = { 1, 2, 3, 4, 5 };
for (size_t i = 0; i < vArray.size(); ++i) {
  sum += 2*vArray[i];
}


Better yet!

int sum = 0;
std::vector<int> vArray = { 1, 2, 3, 4, 5 };
for (int x : vArray) {
  sum += 2*x;
}


I'm not seeing any elegant use of lambda expressions. Seeing functor definitions as parameters to other functions looks weird and messy. You could also just write a functor in an unnamed namespace to prevent namespace pollution. The functor could be named something intuitive like:

namespace {
  struct NickEquals {
    // ...
  };
} // only valid in this translation unit

auto itr = std::find_if(std::begin(vUsers), std::end(vUsers), NickEquals("nslay")); // Find If Nick Equals "nslay" ... reads nicely!


Another one I have mixed feelings about is the auto type specifier. Yes, it is very convenient to write, but it's not very readable.


auto thing = Blah(); // So, what does Blah() return? Oh, right, best go look in the header. Oh, and did I mention 'auto' also consumes constness and pointers too (but not references)? Blah() might return a pointer ... or maybe a const. You'd never guess that by looking at it though.

// Oh yeah, If I changed Blah()'s return type, maybe it still compiles and runs when it shouldn't.

for (auto &x : vArray) {
  // Wait, what is x again?
}


Anyone else have such thoughts?
An adorable giant isopod!

while1

#1
IMO the STL for_each() w/ lambdas is more readable than the traditional for loop for a trivial for loop where one iterates through summing the entirety of the data structure from beginning to end.  However, I consider the STL for_each() less readable than the new foreach loop syntax (yay for C++11!)  IMO, the STL for_each() and the new foreach loop both provide solutions to a shared problem- wasting time writing and reading trivial for loops.  The new foreach loop is the better solution though IMO and makes the STL for_each irrelevant (although there may be scenarios where it excels?)

I'd be more interested in the performance difference.  Correct me if I'm wrong, but the STL for_each() is going to be slowest of the three.

As to the readability the "auto" feature, or implicit typing of local variables (inferred by the compiler), I would say I also have mixed feelings about it.  C# has had this feature for years except it's "var" instead of "auto".  At first I wasn't too keen on using it at all, but I've found myself using it generally when the convenience in writeability outweighs the detriment to readability.  In other words, usually only when I one can infer the type by simply looking to the right of the assignment operator.  I agree though, it's a lot more complicated for C++ because of pointers and constness.  Although, I think that readability can be significantly mitigated by use of a modern IDE.
I tend to edit my topics and replies frequently.

http://www.operationsmile.org