Maestro
Maestro

Reputation: 2572

Why I can't pass an array to function template?

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."

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.

Upvotes: 2

Views: 373

Answers (2)

cigien
cigien

Reputation: 60412

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&); 

Upvotes: 6

Your example with the same array sizes would work, if you would change the function template

from:

template <typename T> T fref(const T&, const T&); // references

to:

template <typename T> const T& fref(const T&, const T&); // references

It depends on what you intent to return.

Upvotes: 0

Related Questions