int native_array[2][3][4];
int cnt = 1;
for( auto x : native_array)
{
// TYPE OF x is int (*)[4]
for( auto y : *x)
{
cout << cnt++ << " " << flush;
}
}
The type of x is reported as int (*)[4], but it should be int (*)[3][4]. The number of elements printed to the console is 8 ( 2 X 4) but it should be 12!
#include <iostream>
int main()
{
int native_array[2][3][4] {} ;
int n = 0 ;
for( auto& array_2d : native_array ) // type of array_2d is int (&)[3][4]for( auto& row : array_2d ) // type of row is int (&)[4]for( int& item : row ) item = n++ ;
for( constauto& array_2d : native_array ) // type of array_2d is const int (&)[3][4]
{
for( constauto& row : array_2d ) // type of row is const int (&)[4]
{
for( int item : row ) std::cout << item << ' ' ;
std::cout << '\n' ;
}
std::cout << "\n\n" ;
}
}
I have the following reasoning which I would like to confirm:
in the code I provided above, x is the first element of native_array which is arr[0], which is an array and therefore x is an address ( &arr[0][0] ) which has type int (*)[4].
It seems to me this is correct and it would answer my original question.
Just curious: is my pointer arithmetic analysis of the situation correct? It seems to explain why using auto any value instead of auto by reference does not work.
> is my pointer arithmetic analysis of the situation correct?
Yes; since x is a value, array-to-pointer decay takes place.
1 2 3 4
for( auto x : native_array )
{
// ...
}
is shorthand for
1 2 3 4 5 6 7 8 9
auto&& range = native_array ;
auto begin = std::begin(range) ;
auto end = std::end(range) ;
for( ; begin != end ; ++begin )
{
auto x = *begin ; // *begin is non-copyable, therefore array to pointer decay
// ...
}
There is a way to find out the type of any variable using this:
1 2
template<typename T>
struct AType;
This is an undefined struct so it reports the type when we use it like so:
AType<decltype(x)> x_decl;
BTW, jlb, why are you taking the address of native_array in your sizeof() statements? This will not give you the size...
If you use the above struct to find the type of x in my original 'range for' you will find the type of x is indeed as I said (int (*)[4]) and that my pointer arithmetic analysis is correct.
BTW, jlb, why are you taking the address of native_array in your sizeof() statements? This will not give you the size...
Because that is what you asked about:
in the code I provided above, x is the first element of native_array which is arr[0], which is an array and therefore x is an address ( &arr[0][0] ) which has type int (*)[4].