Using iterators on arrays
An array is converted to a pointer easily, but not always. For example, if you take the address of the array or get a reference then the original array type isn't lost:
int a[10];int (&ar)[10] = a; // fineint (*ap)[10] = &a; // also fine
However, when you use an array in a way where most other types would be copied, the array is converted to a pointer and the pointer is copied instead.
In your example, you can use arr2 if you make it be a reference:
auto &arr2 = arr;
Now arr2
has type int (&)[10]
instead of int *
.
Because std::begin
is defined for arrays but not for pointers. An array type is not the same as a pointer type.
The problem here is that apparently the auto arr2 = arr
degrades the type from the array type to a pointer type.
Note that the problem is actually in std::end
not in std::begin
. After all how would std::end
be able to give the pointer to the last+1 element when all it has is a pointer to the first element? It can't, therefore std::end
cannot be defined for a pointer type and hence std::begin
does not make any sense for a pointer type.
To be precise the type of arr
is int[10]
while that of arr2
and arr3
is int*
. The former can degrade into the latter but not vice versa.
Here, auto
will decay the arr
(array type) to a pointer. And both std::begin
and std::end
can only work for containers or arrays, but not for pointers.
From C++11 standard
ยง7.1.6.4 auto specifier [dcl.spec.auto]
1 The auto type-specifier signifies that the type of a variable being declared shall be deduced from its initializeror that a function declarator shall include a trailing-return-type.
You code cannot work here as auto
cannot deduce array types. Just like:
char a[5];auto b[5] = a; // error, a evaluates to a pointer, which does // not match the array type
To make it work, just use C++ containers like std::vector
:
vector<int> arr = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };