Reputation: 5034
I have these C++ codes:
In "header1.h"
template <typename T>
int f1(const T& t1) {
return 0;
}
extern const int p[];
in cpptests.cpp
#include "header1.h"
int _tmain(int argc, _TCHAR* argv[]) {
f1(p);
return 0;
}
And in VC++2010, I got this compile error:
c:\work\cpptests\cpptests\cpptests.cpp(10): error C2664: 'f1' : cannot convert parameter 1 from 'const int []' to 'const int (&)[1]'
Reason: cannot convert from 'const int []' to 'const int [1]'
There is no context in which this conversion is possible
Generating Code...
Wny does the template function call convert p to const int (&)[1]
?
Upvotes: 2
Views: 912
Reputation: 477040
The type of your variable p
is "array of unknown bound of const int
". By C++11 8.3.5, "Functions",
If the type of a parameter includes a type of the form [...] “reference to array of unknown bound of
T
,” the program is ill-formed.
Allow me a little mental excursion on why this makes sense:
You may know that even if a type T
is incomplete, the types T *
and T &
are complete types. C++ contains a curious mechanism by which the type of a variable may change by virtue of being completed. That is, you can declare a variable T x;
which has incomplete type, but later complete the type in the variable's definition. For example, take T = int[]
:
extern int a[]; // `a` has incomplete type "array of unknown bound of int"
int a[10]; // now `a` has complete type "array of 10 int"
However (cf. 3.9/6), suppose now that we have another variable of pointer type T *
:
int (*p)[] = &a; // `p` is a pointer to an array of unknown bound
The type of this variable is already complete, but the "array" part of it can never be completed. So even if a
may eventually have a complete type, the type p
can never change. Its type will never become int (*)[10]
. Both types are already complete, and the latter is not a completion of the former.
That means that you can never use p
to access the entire array object as a whole. You can still use p
by decaying *p
to a pointer to the first element of the array (note that *p
is a perfectly fine lvalue; glvalues need not have complete types), but you can never see the whole array through p
. (The same reasoning applies to T &
.)
Since pointers and references to arrays of unknown bound have such limited utility, they are not allowed as function parameter types. In your case, the deduced type is precisely an "array of unknown bound" type, and so the resulting program is ill-formed.
Upvotes: 3