1,105,169 Community Members

Multidimensional array & pointer in range for loops

Member Avatar
Vasthor
Junior Poster
110 posts since Oct 2011
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 

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. :/

Member Avatar
CGSMCMLXXV
Junior Poster in Training
54 posts since Jan 2013
Reputation Points: 5 [?]
Q&As Helped to Solve: 7 [?]
Skill Endorsements: 0 [?]
 
0
 

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. ;)

Member Avatar
Vasthor
Junior Poster
110 posts since Oct 2011
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 

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?

Member Avatar
vijayan121
Posting Virtuoso
1,769 posts since Dec 2006
Reputation Points: 1,097 [?]
Q&As Helped to Solve: 329 [?]
Skill Endorsements: 16 [?]
 
1
 

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 ***
Member Avatar
Tumlee
Posting Whiz in Training
203 posts since Oct 2011
Reputation Points: 42 [?]
Q&As Helped to Solve: 41 [?]
Skill Endorsements: 4 [?]
 
1
 

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.

You
This article has been dead for over three months: Start a new discussion instead
Post:
Start New Discussion
View similar articles that have also been tagged: