23

I'm trying to learn c++, so I wrote a short program that uses the new c++11 for loop, which makes the compiler give me an error I don't understand. this is my c++ code:

#include <iostream>
#include <cmath>
using namespace std;

float legge_oraria_moto_accelerato(float a[3]){
    return a[2]*a[0] + 0.5*a[1]*a[0]*a[0];
}
int corri(float (f)(float array[3]), float arrays[3][3])
    { for(auto i:arrays) cout << f(i) << '\n';
    return 0;
} 

int main()
{ 
return 0;
}

and this is the compiler's (g++ -std=gnu++11) error:

mezzo.cpp: In function ‘int corri(float (*)(float*), float (*)[3])’:
mezzo.cpp:9:18: error: ‘begin’ was not declared in this scope
     { for(auto i:arrays) cout << f(i) << '\n';
                  ^
mezzo.cpp:9:18: note: suggested alternatives:
In file included from /usr/include/c++/4.9/bits/basic_string.h:42:0,
                 from /usr/include/c++/4.9/string:52,
                 from /usr/include/c++/4.9/bits/locale_classes.h:40,
                 from /usr/include/c++/4.9/bits/ios_base.h:41,
                 from /usr/include/c++/4.9/ios:42,
                 from /usr/include/c++/4.9/ostream:38,
                 from /usr/include/c++/4.9/iostream:39,
                 from mezzo.cpp:1:
/usr/include/c++/4.9/initializer_list:89:5: note:   ‘std::begin’
     begin(initializer_list<_Tp> __ils) noexcept
     ^
/usr/include/c++/4.9/initializer_list:89:5: note:   ‘std::begin’
mezzo.cpp:9:18: error: ‘end’ was not declared in this scope
     { for(auto i:arrays) cout << f(i) << '\n';
                  ^
mezzo.cpp:9:18: note: suggested alternatives:
In file included from /usr/include/c++/4.9/bits/basic_string.h:42:0,
                 from /usr/include/c++/4.9/string:52,
                 from /usr/include/c++/4.9/bits/locale_classes.h:40,
                 from /usr/include/c++/4.9/bits/ios_base.h:41,
                 from /usr/include/c++/4.9/ios:42,
                 from /usr/include/c++/4.9/ostream:38,
                 from /usr/include/c++/4.9/iostream:39,
                 from mezzo.cpp:1:
/usr/include/c++/4.9/initializer_list:99:5: note:   ‘std::end’
     end(initializer_list<_Tp> __ils) noexcept
     ^
/usr/include/c++/4.9/initializer_list:99:5: note:   ‘std::end’
Piotr Skotnicki
  • 46,953
  • 7
  • 118
  • 160
bercio
  • 341
  • 1
  • 2
  • 4

1 Answers1

40

Range-based for loops work with arrays, but not with pointers. The issue here is that arrays is actually a pointer and not an array.

When you have a function parameter that is declared as an array, it is adjusted to a pointer type. You can see this here with the parameter float arrays[3][3]: In the compiler error message you can see that the actual parameter type is a pointer to an array float (*)[3], which can't be used with a ranged-based for loop.

If you pass the array by reference instead (float (&arrays)[3][3]), it won't adjusted to a pointer in this manner and will therefore work with the range-based for loop.

interjay
  • 107,303
  • 21
  • 270
  • 254
  • 2
    @bitmask this post does not claim that pointers are arrays or vice versa – M.M Mar 04 '15 at 12:17
  • The standardese for the array-to-pointer type change in function parameters is *adjusted*. – T.C. Mar 04 '15 at 12:17
  • 1
    To complete this great answer.. the inside `for` should looks like `for( float (&row)[3] : arrays) cout << f(row) << '\n';` http://coliru.stacked-crooked.com/a/affd16b1d14938e2 – hlscalon Mar 04 '15 at 12:22
  • @LightnessRacesinOrbit of course, without using `auto` (why don't use it, I don't know :) ) – hlscalon Mar 04 '15 at 12:59
  • thanks a lot, very well explained, I understand the issue now. It's hard for me to get the hang of pointers and references, coming from python. – bercio Mar 05 '15 at 19:08
  • shouldn't this be accepted as an answer? – berkus Jan 01 '22 at 10:57