Reputation: 105
In the code below, we don't dereference y
(it is error in fact), but we do dereference z
. Can someone explain why so?
#include <iostream>
#include <vector>
int main()
{
std::vector <int> x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
for( auto y : x )
std::cout << y << " ";
std::cout<<std::endl;
for(auto z = x.begin();z!=x.end();++z)
std::cout<<*z<<" ";
}
Upvotes: 0
Views: 76
Reputation: 11002
In the code below, we don't dereference
y
(it is error in fact), but we do dereferencez
. Can someone explain why so?
We don't because the compiler does.
The range based for loop: auto y : x
also uses the begin
and end
functions, and it dereferences the iterators for you. It is equivalent to the following syntax:
auto && __range = range_expression; // reference that we'll get to use
auto __begin = begin_expr; // get iterator
auto __end = end_expr;
for(; __begin != __end; ++__begin) {
range_declaration = *__begin; // dereference iterator
loop_statement
}
The iterators in turn perform the dereferencing by having overloaded the *
operator to return a reference.
So in the question the second part actually does exactly what the range based for does for you 'behind the scenes'.
Upvotes: 1
Reputation: 2498
The second construct is an explicit way of loop iteration via iterators.
The first one is a syntactic sugar. You can read about it here: http://en.cppreference.com/w/cpp/language/range-for. It can be seen there that the construct is transformed into something like:
auto && __range = range_expression ;
auto __begin = begin_expr ;
auto __end = end_expr ;
for ( ; __begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
The key place for understanding is range_declaration = *__begin. Here range_declaration is y and it is assigned from real iterator.
Upvotes: 2
Reputation: 7111
Because you are using two different types. auto y : x
is saying that y
will be the actual element itself (1
, 2
etc), whereas auto z = x.begin()
is saying that z
will be nn iterator
, which you need to dereference to get the actual value.
You should simply prefer to use the first, because the code is shorter and more easily readable.
Upvotes: 1