Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Will range based for loop in c++ preserve the index order

In c++11, if I use a range based for loop on vector, will it guarantee the iteration order?

i.e. are the following code blocks guaranteed to produce the same output?

vector<T> output;
vector<U> V;
for( auto v: V) output.push_back(f(v));

vs

for(int i =0; i < V.size(); ++i) output.push_back(f(V[i])); 

what if it is not vector but map, etc?

like image 517
ahala Avatar asked Sep 27 '13 13:09

ahala


People also ask

Which order is correct for a for loop?

So first the condition is checked, then the loop body is executed, then the increment.

Does C have range based for loops?

Range-based for loop in C++ It executes a for loop over a range. Used as a more readable equivalent to the traditional for loop operating over a range of values, such as all elements in a container.

Are range based for loops faster?

Range-for is as fast as possible since it caches the end iterator[citationprovided], uses pre-increment and only dereferences the iterator once. Then, yes, range-for may be slightly faster, since it's also easier to write there's no reason not to use it (when appropriate).

Can we use a double value as in index in a for loop?

Yes, it is, there is no restriction about it. In C++ is also very common creating for loops with iterators.


2 Answers

Yes the two codes are guaranteed to do the same. Though I don't have a link to the standard you can have a look here. I quote: You can read that as "for all x in v" going through starting with v.begin() and iterating to v.end().

like image 114
Ivaylo Strandjev Avatar answered Oct 20 '22 01:10

Ivaylo Strandjev


Yes, they are equivalent. The standard guarantees in 6.5.4:

For a range-based for statement of the form

for ( for-range-declaration : expression ) statement

let range-init be equivalent to the expression surrounded by parentheses ( expression )

and for a range-based for statement of the form

for ( for-range-declaration : braced-init-list ) statement

let range-init be equivalent to the braced-init-list. In each case, a range-based for statement is equivalent to

{
  auto && __range = range-init;
  for ( auto __begin = begin-expr,
      __end = end-expr;
      __begin != __end;
      ++__begin ) {
    for-range-declaration = *__begin;
    statement
  }
}

where __range, __begin, and __end are variables defined for exposition only, and _RangeT is the type of the expression, and begin-expr and end-expr are determined as follows:

— if _RangeT is an array type, begin-expr and end-expr are __range and __range + __bound, respectively, where __bound is the array bound. If _RangeT is an array of unknown size or an array of incomplete type, the program is ill-formed;

— if _RangeT is a class type, the unqualified-ids begin and end are looked up in the scope of class _RangeT as if by class member access lookup (3.4.5), and if either (or both) finds at least one declaration, begin-expr and end-expr are __range.begin() and __range.end(), respectively;

— otherwise, begin-expr and end-expr are begin(__range) and end(__range), respectively, where begin and end are looked up with argument-dependent lookup (3.4.2). For the purposes of this name lookup, namespace std is an associated namespace.

Though your question about map is a bit nonsensical. If it's an ordered map and you iterate through the map properly, then they're equivalent. If it's an unordered map then your question doesn't really make much sense.

like image 22
OmnipotentEntity Avatar answered Oct 20 '22 02:10

OmnipotentEntity