What is the most effective way of iterating a std::vector and why?

range-based for loop c++
c++ vector for
iterate through vector of objects c++
c++ auto iterator
std::iterator
c++ iterator for loop
std vector begin
iterate through 2d vector c++

In terms of space-time complexity which of the following is best way to iterate over a std::vector and why?

Way 1:

for(std::vector<T>::iterator it = v.begin(); it != v.end(); ++it) {
    /* std::cout << *it; ... */
}

Way 2:

for(std::vector<int>::size_type i = 0; i != v.size(); i++) {
    /* std::cout << v[i]; ... */
}

Way 3:

for(size_t i = 0; i != v.size(); i++) {
    /* std::cout << v[i]; ... */
}

Way 4:

for(auto const& value: a) {
     /* std::cout << value; ... */

First of all, Way 2 and Way 3 are identical in practically all standard library implementations.

Apart from that, the options you posted are almost equivalent. The only notable difference is that in Way 1 and Way 2/3, you rely on the compiler to optimize the call to v.end() and v.size() out. If that assumption is correct, there is no performance difference between the loops.

If it's not, Way 4 is the most efficient. Recall how a range based for loop expands to

{
   auto && __range = range_expression ;
   auto __begin = begin_expr ;
   auto __end = end_expr ;
   for ( ; __begin != __end; ++__begin) {
      range_declaration = *__begin;
      loop_statement
   }
}

The important part here is that this guarantees the end_expr to be evaluated only once. Also note that for the range based for loop to be the most efficient iteration, you must not change how the dereferencing of the iterator is handled, e.g.

for (auto value: a) { /* ... */ }

this copies each element of the vector into the loop variable value, which is likely to be slower than for (const auto& value : a), depending on the size of the elements in the vector.

Note that with the parallel algorithm facilities in C++17, you can also try out

#include <algorithm>
#include <execution>

std::for_each(std::par_unseq, a.cbegin(), a.cend(),
   [](const auto& e) { /* do stuff... */ });

but whether this is faster than an ordinary loop depends on may circumstantial details.

C++, You can iterate over a std::vector in several ways. Accessing the vector's content by index is much more efficient when following the row-major order principle. c++ - What is the most effective way to get the index of an iterator of an std::vector? Translate I'm iterating over a vector and need the index the iterator is currently pointing at.

How to iterate through a Vector without using Iterators in C++ , The iterator is not the only way to iterate through any STL container. There exists a better and efficient way to iterate through vector without using iterators. using namespace std; Simple and easy to write code. types of range-based for loop iterators in C++ � vector::begin() and vector::end() in C++ STL� In particular their iterator_category is std::output_iterator_tag, and the other types are void. My understanding as to why the last 4 types must be void is that they are not used anyway. With std::iterator, we used to define output iterators this way:

Addition to lubgr's answer:

Unless you discover via profiling the code in question to be a bottleneck, efficiency (which you probably meant instead of 'effectivity') shouldn't be your first concern, at least not on this level of code. Much more important are code readability and maintainability! So you should select the loop variant that reads best, which usually is way 4.

Indices can be useful if you have steps greater than 1 (whyever you would need to...):

for(size_t i = 0; i < v.size(); i += 2) { ... }

While += 2 per se is legal on iterators, too, you risk undefined behaviour at loop end if the vector has odd size because you increment past the one past the end position! (Generally spoken: If you increment by n, you get UB if size is not an exact multiple of n.) So you need additional code to catch this, while you don't with the index variant...

Efficient way of using std::vector, But std::vector is just a wrapper over a dynamically allocated array that also Method 3: Use traditional loop, traverse vector using its iterator. int and reallocation and using raw pointer to access its data is the best way to go. Returns a std::vector<T> containing an element-by-element copy of the input container in whatever order accomplished by iterating the input container from beginning to end. Something non-functioning would be like follows: template<typename Iterator, typename T> std::vector<T> dumb_copy(Iterator first, Iterator last) {

How to iterate through a vector using for loop in C++, traditional index based - good for vectorized environments There are three ways of iterating over a vector in C++ : typedef std::vector <int >::iterator tIntIter;. How do I erase an element from std::vector<> by index? Why is the C++ STL is so heavily based on templates?(and not on*interfaces*) What is the most effective way to get the index of an iterator of an std::vector? Deleting elements from STL set while iterating

For completeness, I wanted to mention that your loop might want to change the size of the vector.

std::vector<int> v = get_some_data();
for (std::size_t i=0; i<v.size(); ++i)
{
    int x = some_function(v[i]);
    if(x) v.push_back(x);
}

In such an example you have to use indices and you have to re-evaluate v.size() in every iteration.

If you do the same with a range-based for loop or with iterators, you might end up with undefined behavior since adding new elements to a vector might invalidate your iterators.

By the way, I prefer to use while-loops for such cases over for-loops but that's another story.

Why is using classic for loops as iterators in stl considered bad , But using a for loop with iterators is more generic. and doesn't require that the container have index-based accessors at all (let alone efficient ones). int total = 0; for (std::vector<int>::iterator p = v.begin(); p!= v.end(); ++p) total += *p; don't care how many lines the file has, it is needed only to construct a loop in this way. -the most efficient and effective method of conveying information to and within development team is face-to-face conversation -working software is the primary measure of progress -the best architectures, requirements and designs emerge from self organizing teams

std::vector and range-based for loops, There are other constructors, such as std::vector(size_t count, const T& t) that initializes that copies values out of some other container (I'll talk about that more below). The iterator methods enable you to use the range-based for loop. write a custom iterator type makes it possible to implement more efficient algorithms. Segfault when deselecting iterator for pointer vector I have a vector of object pointers std::vector<Element*> elements; When iterating through the vector, I would like to double dereference the iterator in order to call the object's methods. std::cout << (*it)->getName() << std::en

6.12a — For-each loops, std::cout << "The best score was " << maxScore << '\n';. return 0;. } While for loops provide a convenient and flexible way to iterate through an array, they are also easy to mess up std::vector<int> fibonacci{ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 }; . The forward iterator only allows movement one way -- from the front of the container to the back. To move from one element to the next, the increment operator, ++, can be used. For instance, if you want to access the elements of an STL vector, it's best to use an iterator instead of the traditional C-style code.

std::vector, 1) std::vector is a sequence container that encapsulates dynamic size arrays. Vectors usually occupy more space than static arrays, because more memory This way a vector does not need to reallocate each time an element is space- efficient dynamic bitset returns a reverse iterator to the beginning 1.Size of the Vector 2.Insert Element into the Vector 3.Resize the vector 4.Display by Iterator 5.Exit Enter your Choice: 1 Size of Vector: 0 1.Size of the Vector 2.Insert Element into the Vector 3.Resize the vector 4.Display by Iterator 5.Exit Enter your Choice: 2 Enter value to be inserted: 1 1.Size of the Vector 2.Insert Element into the

Comments
  • Possible duplicate of What are the complexity guarantees of the standard containers?
  • They are equivalent. Sometimes the compiler may even turn one into the other.
  • Way 5: for(auto&& value: a) { is the best.
  • They are equally effective. If you want to know which one is more efficient, consider changing the title of the question.
  • You need to grok that C++ is an abstraction. Your computer does not execute these statements. You are describing the behaviour of a program, and all those descriptions are exactly the same.
  • Good luck finding those C++17 features in a compiler. Those features are virtually non existant. I wish the compilers would just implement the Intel STL version and be done with it already
  • @bremen_matt AFAIK, GCC is really the odd man out here, and both clang and MSVC implement this already?
  • The parallel versions? That is, std::par_unseq
  • I don't know about that... I can't get a simple code to compile with either GCC head or Clang head: wandbox.org/permlink/cnCxFscI0SWV1UF0
  • One place I found tracking the progress is: en.cppreference.com/w/cpp/compiler_support
  • Out of interest, why didn't you consider for (auto&& element : vec)?
  • @Bathsheba: I find it confusing. We know that it will be a reference, so why mark it as a universal reference?
  • To add on why this should not be considered: either the compiler cannot optimize this and there is no point to use the tools provided by the Standard Library (<vector>, <algorithm>, etc.) if you expect a minimum of performance; either it does (and it does and losing time and effort on this minor difference never matters unless you pinpoint through a profiler a bottleneck in your implementation.
  • An important supplemental answer because the OP's question specifically called out iterating over std::vector - as opposed to iterating over an arbitrary STL-ish container.
  • "On a somewhat funny note, the compiler implements method3 as a jmp instruction to method2." It does that because the backend code generator knows that they are equivalent (in other words, they produce exactly the same machine code).