Possible Duplicate: Calculating size of an array
This question has been asked before, but I want to confirm it. Let's say I have the following C++ function:
#include <stdio.h>
#include <stdin.h>
#define length(a) sizeof(a)/sizeof(a[0])
int main()
{
double c[] = {1.0, 2.0, 3.0};
printf("%d\n", getLength(c));
return 0;
}
int getLength(double c[]) { return length(c);}
This should return the wrong value because size of will return the size of the pointer as opposed to the size of the array being pointed at. This:
template<typename T, int size>
int length(T(&)[size]){return size;}
I know it works directly, but I want to know if I can somehow call it indirectly i.e. via a helper function. I understand that two possible alternatives are to either store the length of the array in a separate slot or use a vector, but what I want to know is:
Given a function getLength:
getLength(double arr[])
{
...
}
Is there a way to compute the length of arr
without passing any more information?
The question boils down to the difference between compile-time information and run-time information.
The template works because the size of the array is known at compile time, and the template is evaluated at compile time.
The other function doesn't work, because all that's known at compile time is that the function will be called with an array. The size of the array isn't specified in the function prototype. There's no run-time information passed about the size of the array either, unless you add another parameter and pass it explicitly.
The template version would work. Who said it will not work?
template<typename T, int size>
int length(T(&)[size])
{
return size;
}
This is correct. It will return the length of the array. You just need to call this function directly. It seems you want to call this function from getLength()
. Don't do that, because the way you've written getLength
function is equivalent to this:
int getLength(double *c) { return length(c);}
There is absolutely no difference between your written getLength()
and the above version. That is, once you call this function, (or your function), the array is already decayed into a pointer to double. You've already lost the size
information with the decay of the array (which is why this is called decaying of array
). So you should NOT call this function, instead call the length()
function directly..
However, there is little problem with length()
as well. You cannot use this function where const-expression is needed, as such:
int anotherArray[length(c) * 10]; //error
So the solution would be this:
template < std::size_t N >
struct value2type { typedef char type[N]; };
template < typename T, std::size_t size >
typename value2type<size>::type& sizeof_array_helper(T(&)[size]);
#define length(a) sizeof(sizeof_array_helper(a))
Now you can write:
int anotherArray[length(c) * 10]; //ok
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