I have this example from C++ 5th ed.:
template <typename T> T fobj(T, T); // arguments are copied
template <typename T> T fref(const T&, const T&); // references
string s1("a value");
const string s2("another value");
fobj(s1, s2); // calls fobj(string, string); const is ignored
fref(s1, s2); // calls fref(const string&, const string&)
// uses premissible conversion to const on s1
int a[10], b[42];
fobj(a, b); // calls f(int*, int*)
fref(a, b); // error: array types don't match
"In the next pair of calls, we pass array arguments in which the arrays are different sizes and hence have different types. In the call to fobj
, the fact that the array types differ doesn’t matter. Both arrays are converted to pointers. The template parameter type in fobj
is int*
. The call to fref
, however, is illegal. When the parameter is a reference, the arrays are not converted to pointers (§ 6.2.4, p. 217). The types of a
and b
don’t match, so the call is in error."
I have only a confusion about the last call fref(a, b)
: Why it is illegal?
I think because the size of an array is a part of its type it is OK until here so a
has the type int[10]
while b
has the type int[42]
But the problem is whatever I try to make the size the same it fails to compile:
int a[10], b[10];
fref(a, b); // error: array types don't match
int a[10], b[42];
fref(a, a); // error: array types don't match
As you can see I've made a
and b
of the same type nevertheless it still fails to compile and even if I pass the same array a
or b
twice to fref
it fails.
So why I still get error: array types don't match
? thank you.
a
and b
don’t match, so the call is in error". And there's another problem because I've made the arrays of the same type and still don't work.For this function template:
template <typename T>
T fref(const T&, const T&);
when you make the call:
int a[42];
fref(a, a);
template argument deduction will deduce T
to be int[42]
. The call fails to compile, but the reason in your question, i.e. // error: array types don't match
is incorrect, because the array types do indeed match.
The reason the call fails to compile is because the return type is also T
, and you cannot return array types, such as int[42]
from a function.
You can fix this in any way such that fref
has a valid return type, e.g. you could return void
:
template <typename T> void fref(const T&, const T&);