What happens when a short int[] is automatically cast to long int[]?
In C++, if I have an array of short ints and pass it as an argument to a function that takes an array of long ints, will the function see each value of the short array cast to a long int or will the entire array be reinterpreted into an array of long ints of n/2 elements?开发者_如何转开发
You can't because there's no automatic cast that can be used.
Remember that you can't pass an array to a function by value: an array parameter is really just a pointer parameter, so the following two are the same:
void f(long a[]);
void f(long* a);
When you pass an array to a function, the array is implicitly converted to a pointer to its initial element. So, given long data[10];
, the following two are the same:
f(data);
f(&data[0]);
There is no implicit conversion from short*
to long*
, so if data
were declared as short data[10];
, you would get a compilation error.
You would need to explicitly cast the short*
to a long*
, using reinterpret_cast
, but that won't convert "an array of N short
elements" into "an array of N long
elements," it will reinterpret the pointed-to data as "an array of [some number of] long
elements," which probably isn't what you want.
You need to create a new array of long
elements and copy the elements from the array of short
into the array of long
:
short data[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
long data_as_long[10];
std::copy(data, data + 10, data_as_long);
f(data_as_long);
Or, you might consider changing your function to be a template that can accept a pointer to an array of any type of element:
template <typename T> void f(T*);
Or, for a more advanced solution, the most generic way to do this would be to have your function take an iterator range. This way, you could pass it any type of iterator (including pointers into an array). In addition, it provides a natural and simple way to ensure that the length of the array is passed correctly, since the length is not passed explicitly, it's determined by the arguments.
template <typename Iterator> void f(Iterator first, Iterator last);
const unsigned length_of_data = 10;
long data_array[length_of_data];
std::vector<long> data_vector(length_of_data);
f(data_array, data_array + length_of_data); // works!
f(data_vector.begin(), data_vector.end()); // also works!
No, a good compiler will give an error. A bad compiler will give strange results.
Recasting a single element at a time is common and presents no difficulties, but passing a pointer to a function expecting one type of object and receiving another is an I Love Lucy sort of catastrophe.
精彩评论