c++ - Use vs. misuse of generic algorithms -


to make discussion concrete, suppose simple example problem: user enters several one-digit numbers without spaces, presses enter , gets sum of these numbers. so, user session can this:

> 1231 7 > 12 3 > 0123 6 > ^d 

i learning c++ going through c++ primer (5th edition). before learning chapter 10 on generic algorithms, solve above problem in following naive way:

int main() {     std::cout << "> ";     std::string word;     while (std::cin >> word) {         auto sum = 0;         (auto c : word) sum += c - '0';         std::cout << sum << std::endl << "> ";     }     return 0; }  

here how solved same problem armed generic algorithms:

int main() {     std::cout << "> ";     std::istream_iterator<std::string> in(std::cin), eof;     std::for_each(in, eof,                   [](const std::string &word) {                       std::cout << std::accumulate                           (word.cbegin(), word.cend(), 0,                            [](int cur, char ch) {                                return cur + (ch - '0');                            }) << std::endl << "> ";                   });     return 0; } 

to tell truth, first solution more. it's short , easy read. second solution sacrifices both brevity , clarity on altar of c++11's standard library.

my question three-fold:

  1. am correct in comparison of 2 solutions?

  2. is there better way solve example problem using standard library's capabilities?

  3. if naive solution best 1 in case, real use cases capabilities of c++11's standard library used in example?


edit: actually, should have gone way i/o iterators. after cleaning little, got. comments?

int main() {     std::cout << "> ";     std::istream_iterator<std::string> in(std::cin), eof;     std::ostream_iterator<int> out(std::cout, "\n> ");     using cstrr = const std::string &;     auto myadd = [](int acc, char ch) {return acc + (ch - '0');};     auto mysum = [&](cstrr word) {         out = std::accumulate(word.cbegin(), word.cend(), 0, myadd);     };     std::for_each(in, eof, mysum);     return 0; } 

you write simpler. example

auto sum = std::accumulate( std::istream_iterator<char>( std::cin ),                              std::istream_iterator<char>(),                             0, []( auto acc, auto c ) { return acc += c -'0'; } );   std::cout << sum << std::endl; 

or

#include <iostream> #include <numeric> #include <string>  int main() {     std::cout << "> ";      std::string word;      while ( std::cin >> word )      {         auto sum = std::accumulate( word.begin(), word.end(), 0,                                      []( int acc, char c ) { return acc += c - '0'; } );         std::cout << sum << std::endl << "> ";     } }     

though indeed better use ordinary loops instead of compound algorithm records.:)


Comments