Should I use std::for_each?

前端 未结 9 1311
自闭症患者
自闭症患者 2020-12-08 04:18

I\'m always trying to learn more about the languages I use (different styles, frameworks, patterns, etc). I\'ve noticed that I never use std::for_each so I thought that perh

相关标签:
9条回答
  • 2020-12-08 04:29

    Boost.Range simplifies the use of standard algorithms. For your example you could write:

    boost::for_each(v, [](int n) { cout << n << endl; });
    

    (or boost::copy with an ostream iterator as suggested in other answers).

    0 讨论(0)
  • 2020-12-08 04:30

    Note that the "traditional" example is buggy:

    for(int i=0; i<v.size(); i++) { cout << v[i] << endl; }
    

    This assumes that int can always represent the index of every value in the vector. There are actually two ways this can go wrong.

    One is that int may be of lower rank than std::vector<T>::size_type. On a 32-bit machine, ints are typically 32-bits wide but v.size() will almost certainly be 64 bits wide. If you manage to stuff 2^32 elements into the vector, your index will never reach the end.

    The second problem is that you're comparing a signed value (int) to an unsigned value (std::vector<T>::size_type). So even if they were of the same rank, when the size exceeds the maximum integer value, then the index will overflow and trigger undefined behavior.

    You may have prior knowledge that, for this vector, those error conditions will never be true. But you'd either have to ignore or disable the compiler warnings. And if you disable them, then you don't get the benefit of those warnings helping you find actual bugs elsewhere in your code. (I've spent lots of time tracking down bugs that should have been detected by these compiler warnings, if the code had made it feasible to enable them.)

    So, yes, for_each (or any appropriate <algorithm>) is better because it avoids this pernicious abuse of ints. You could also use a range-based for loop or an iterator-based loop with auto.

    An additional advantage to using <algorithm>s or iterators rather than indexes is that it gives you more flexibility to change container types in the future without refactoring all the code that uses it.

    0 讨论(0)
  • 2020-12-08 04:32

    There is an advantage to using std::for_each instead of an old school for loop (or even the newfangled C++0x range-for loop): you can look at the first word of the statement and you know exactly what the statement does.

    When you see the for_each, you know that the operation in the lambda is performed exactly once for each element in the range (assuming no exceptions are thrown). It isn't possible to break out of the loop early before every element has been processed and it isn't possible to skip elements or evaluate the body of the loop for one element multiple times.

    With the for loop, you have to read the entire body of the loop to know what it does. It may have continue, break, or return statements in it that alter the control flow. It may have statements that modify the iterator or index variable(s). There is no way to know without examining the entire loop.

    Herb Sutter discussed the advantages of using algorithms and lambda expressions in a recent presentation to the Northwest C++ Users Group.

    Note that you can actually use the std::copy algorithm here if you'd prefer:

    std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, "\n"));
    
    0 讨论(0)
  • 2020-12-08 04:37

    for_each is the most general of the algorithms that iterate over a sequence, and thus the least expressive. If the goal of the iteration can be expressed in terms of transform, accumulate, copy, I feel that it's better to use the specific algorithm rather than the generic for_each.

    With the new C++0x range for (supported in gcc 4.6.0, try that out!), for_each might even lose its niche of being the most generic way to apply a function to a sequence.

    0 讨论(0)
  • 2020-12-08 04:41

    IMHO, you should try this new features in your test code.

    In the production code you should try the features which you feel comfortable with. (i.e. if you feel comfortable with for_each, you can use it.)

    0 讨论(0)
  • 2020-12-08 04:42

    You can use for loop scoping C++11

    For example:

     T arr[5];
     for (T & x : arr) //use reference if you want write data
     {
     //something stuff...
     }
    

    Where T is every type you want.

    It works for every containers in STL and classic arrays.

    0 讨论(0)
提交回复
热议问题