not working:

    // range for
    for (int (*row)[4] : ia) {
        for (int col : *row) 
            cout << col << " ";

        cout << endl;
    }

    // error: cannot convert 'int*' to 'int (*)[4]' in initialization.

working:

    // range for
    for (int (&row)[4] : ia) {
        for (int col : row) 
            cout << col << " ";

        cout << endl;
    }

yet, i thought either code is similar, either i confused about how pointer works / how range for iteration works. either way, the first code produce type error which should not be there if the second code is working. :/

There is a nice and short explanation about the difference in between derefence and reference operators here:

http://www.cplusplus.com/doc/tutorial/pointers/

These two operators can be tricky sometimes. I know it from my own experience. ;)

I'm sure I'm doing it right.

Source: C++ primer 5th edi.
Note
The parentheses in this declaration are essential:
Click here to view code image
int ip[4]; // array of pointers to int
int (
ip)[4]; // pointer to an array of four ints

and as we know pointer hold the address, so *row should work to obtain the object but not in the code snippet because of "type clash".

that's why I'm actually wonder how range for iteration works, maybe that's the cause.
i even try some random method but it seems I'm out of luck, anyone can clarify why this happen?

either way, the first code produce type error which should not be there if the second code is working. :/

Each element of a two-dimensional array is a one-dimensional array.
Not a pointer to a one-dimensional array.

int a[20] ;
for( int& i : a ) i = 0 ; // fine; the type of element of 'a' is 'int'

for( int* pi : a ) *pi = 0 ; // *** error ***
// the type of element of 'a' is not 'pointer to int'

Likewise,

int b[10][4] ;

// fine; the type of element of 'b' is 'int[4]', 'array of 4 integers'
for( int (&row)[4] : b ) for( int& i : row ) i = 0 ;

// the type of element of 'b' is not 'int(*)[4]', 'pointer to array of 4 integers'
for( int (*ptr_row)[4] : b ) for( int& i : *ptr_row ) i = 0 ; // *** error ***
commented: tyvm!!! +2

When you're using range-based for loops, the variable you declare to the left of the colon must be at type that refers to an element of the array or list on the left. Take the following code:

#include <iostream>

using std::cout;
using std::endl;

int main()
{
    int array[4];

    for(int& element : array)
        element = 3;

    for(int element : array)
        cout << element << endl;

    return 0;
}

The reason the second loop works is obvious --- it's an array full of ints, and element is declared to be an int. The first loop is also acceptable because an int& (reference to an int) can also be used to directly refer to (and modify) elements in the array. If you try to do the following:

for(int* element : array)
    *element = 3;

You will end up with a compiler error. This is because array is an array full of ints, not int*s. Although you could theoretically use pointers to look through an array, this isn't what range-based for is supposed to do. This is essentially why your code is resulting in a compiler error --- the compiler doesn't treat pointers the same way it treats references when it comes to range based for.

commented: thankyou +2
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.