views:

202

answers:

4

I was reading this page : C++ Tip: How To Get Array Length. The writer presented a piece of code to know the size of static arrays.

template<typename T, int size>
int GetArrLength(T(&)[size]){return size;} // what does '(&)' mean ?
.
.
.
int arr[17];
int arrSize = GetArrLength(arr); // arrSize = 17

Could anyone please shed the light on this code, because I couldn't understand how it really works.

+7  A: 

The function is passed a reference (&) to an array of type T, and size size.

jalf
I am sorry but I could not understand why should we pass a reference of an array ? :)
AraK
because that way it doesn't make a copy of the array to pass it in to the function.
Goz
@Goz arrays are not copied in C/C++ when passed, the name of the array is the reference. Am I wrong ?
AraK
@AraK: the array will indeed be passed as a pointer. The code just makes this explicit. It's a needless optimization.
outis
AraK
The only way an array can be passed to a function is as a reference. Arrays can not be passed by value. If you try, it decays to a pointer. And if the function receives a pointer, the array size information has been lost. The only way to make the size information visible to the function is to pass a reference to the array.
jalf
A: 

Wow, that's tricky. I don't know either, but if you keep reading down into the comments on that page:

is essentially

int arr[17]; int arrSize = GetArrLength(arr);

which creates this function:

int GetArrLength(int(&)[17]){return 17;}

So & must mean reference like it always does, so it's taking a reference of the array type and the size (second item in the template) is then the size of the incoming array.

Think I'll stick with old

sizeof(x)/sizeof(x[0])
DougN
the problem with your sizeof trick is that it fails silently if the array decays to a pointer. Then you get the wrong result, but no errors or warnings. The template trick the OP shows will fail to compile if passed a pointer.
jalf
I agree with Jaif (note: +1): Using the reference-array trick is the right way to extract the size of an array. This is how Visual C++ implements its C++ strcpy_s (and similar) functions. The sizeof will fail silently on C++.
paercebal
+1  A: 

sizeof(x)/sizeof(x[0])

Won't catch errors if the array degrads to a pointer type, but it will still compile!

Templated version is bullet proof.

+1  A: 

T(&)[size] is reference to T[size]. If you don't use reference C++ will treat T[size] as T*, and function template parameter deduction would not work.