Re: function overload with array types and pointer types
Am 30.03.2013 07:48, schrieb rigaje@googlemail.com:
I have the following code.
----------------- BEGIN ----------------
#include <cstddef>
#include <type_traits>
template <typename T0, typename T1>
typename std::enable_if<sizeof(T0)==sizeof(T1)>::type
inline f (T0 const* const t0, T1 const* const t1)
{
// do something to *t0 and *t1
}
template <typename T0, typename T1, size_t N0, size_t N1>
typename std::enable_if<sizeof(T0)==sizeof(T1) && N0==N1>::type
inline f (T0 const (&t0) [N0], T1 const (&t1) [N1])
{
for (size_t i = 0; i != N0; ++i)
{
// do something to t0[i] and t1[i]
}
}
int main ()
{
size_t const a [5] {0};
size_t const b [5] {0};
f(a,b);
}
----------------- END ----------------
It was accepted by g++-4.7.0 but rejected by 4.8.0 and all other
compilers I have tested. These facts led me to assume the code
should be rejected according to the standard.
That is correct.
I realize that the array-to-pointer conversion has Exact Match rank
according to Table 12 from 13.3.3.1.1. However, the match to the
second overload is an identity conversion and 13.3.3.2/3 bullet one
reads:
"S1 is a proper subsequence of S2 (comparing the conversion
sequences in the canonical form defined by 13.3.3.1.1, excluding any
Lvalue Transformation; the identity conversion sequence is
considered to be a subsequence of any non-identity conversion
sequence) or ..."
which seems to suggest the second overload should have been
selected.
I have two questions:
(1) 13.3.3.2/3 only says two such implicit conversion sequences are
distinguishable and 13.3.3.2/4 requires standard conversion
sequences to be ordered by their ranks, which seems to mean that
just being distinguishable is not enough to affect overload
resolution, instead, a ranking difference must be present for
overload resolution to work. Am I right?
(2) Another way of understanding 13.3.3.2/3 bullet one is that "the
identity conversion sequence is considered to be a subsequence of
any non-identity conversion sequence" but this "any non-identity
conversion sequence" already excludes Lvalue Transformation as said
earlier in the same sentence. Understanding it this way means the
identity conversion is not distinguishable from the array-to-pointer
conversion for purpose of overload resolution, which also explains
why the code was rejected.
I wonder which of my two understanding is correct, or are they both
wrong? I expect explanations with reference to proper section of the
c++11 standard. Thanks in advance.
My understanding is that the dominating rules for this example are
specified by 14.5.6.2 [temp.func.order] and in particular by 14.8.2.4
[temp.deduct.partial]. Currently there does not exist a partial
ordering between both functions, because array to pointer decay has no
ordering in the rules. There exists already a core language issue for
this unexpected outcome:
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#402
Personally I would strongly prefer to see that a partial ordering will
be defined in the future.
HTH & Greetings from Bremen,
Daniel Kr?gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]