In this case, the compiler does not comply with the standard and is an error. Let's look at the relevant sections.
First of 13.3 / 3 we have:
...
- Firstly, a subset of candidate functions - those that have the correct number of arguments and fulfillment of some other conditions - selected to form a set of viable functions (13.3.2).
- then the best viable function is selected on the basis of implicit (13.3.3.1), necessary to compare each argument with the corresponding parameter of each viable function.
Thus, both functions have the same number of arguments and are considered candidates. Now we have to find the best viable function, in
13.3.3:
let ICSi (F) denote an implicit conversion sequence that converts the ith argument in the list to the type of the ith parameter of the viable function F. 13.3.3.1 determines the implicit conversion sequences and 13.3.3.2 determines what means that one implicit conversion sequence is the best sequence conversion rate or worse conversion sequence than another
Then we have
Given these definitions, a viable function F1 is defined as better than another viable function F2, if for all arguments i, ICSi (F1) is no worse than the transformation scheme than ICSi (F2), and then
- for some argument j, ICSj (F1) is a better conversion sequence than ICSj (F2), or, if it is not,
- F1 is an asymmetric function, and F2 is a template specialization or, if not this,
- F1 and F2 are functions of the template, and the function template for F1 is more specialized than the template for F2 according to the partial ordering of the rules described in 14.5.5.2, or, if not this,
Two functions are equal for the first rule (adding a constant), and the second rule does not apply (both are templates). So, we move on to the third rule. From 14.5.5.2 (which I will indicate upon request) we learn that the version of the const int
function is more specialized than the version of const Item
, so the best match is the const int
overload, which should then be called.
The best interim fix is ββprobably the second overload:
template<size_t SZ> void LoopThrough(int (&Item)[SZ]) { LoopThrough(static_cast<const int (&)[SZ]>(Item)); }