For example, in the main function, I can write int arr[42], and I can use range for loop without indicating its length for (auto i : arr). It works well. Compiler will know its length.
If I pass this array to another function, such as void foo(int arr[]), I cannot use range for loop because the compiler doesn't know its length.
After all, if I have this template template<class T, size_t N> void arr_init(T (&foo)[N]), I can call it by arr_init(x). Obviously, the compiler calls arr_init(int (&)[42]).
I guess the compiler knows the length of array through its declaration int[42]. Am I right? I've got this question when I use range for loop and learn templates. I haven't met such problem before, when I was using C.
The array type T[N] is distinct from the array type T[M] for a type T and two distinct sizes N and M. So, the length of an array is built into the type.
OTOH, arrays are automatically decayed to pointers in a function calls argument list. In other words, there is no distinction between these three function signatures:
int func(int []);
int func(int[5]);
int func(int[10]);
int func(int*);
All the above signatures are simply taking an int*. If you want to preserve the array type, you need to create a function which takes an array reference as an argument. That is exactly what you achieve in your example template<class T, size_t N> void arr_init(T (&foo)[N]). Inside arr_init, foo behaves like an array because it is a reference to an array type.
For an array arr of type T[N], the range-based for uses the expressions arr and arr+N as the start and end points, respectively.
For class types, member functions begin and end, if present, are used to determine the endpoints, failing which the non-member overloads, begin and end are used.
(begin and end, as opposed to std::begin and std::end, since the generic usage of begin and end in the standard library is like this:
using std::begin;
begin(...);
using std::end;
end(...);
This allows ADL to find user-defined begin and end overloads.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With