Date: Sat, 7 Jan 2023 21:16:43 +0000
Hi,
[over.best.ics.general]:
"Implicit conversion sequences are concerned only with the type,
cv-qualification, and value category of the argument and how these are
converted to match the corresponding properties of the parameter."
https://timsong-cpp.github.io/cppwp/n4868/over.match#over.best.ics.general-2
My reading is that the intent of this paragraph is to specify that
viable and best viable functions are selected based on only type + cv +
value category of arguments, and disregard any other property. (This
probably only applies to expression arguments, as initializer list
arguments have non of these properties, but this is just a tangent.)
One example is that a call like `foo(some_obj.bit_field)` could find
`foo(int&)` as viable, and later become ill-formed if this turns out to
be the best viable function for the call.
However this same paragraphs rules out to consider whether the argument
is a null-pointer constant or not. Based on this a call like `foo(0)`
shouldn't find `foo(void *)` viable, as there is no implicit conversion
sequence from a prvalue of type int to `void *`,
Major compilers treat conversion from null-pointer constant to a
pointer type to an implicit conversion sequence and find viable
functions based on that (since forever, AFAIK).
void foo(void *, int); // 1
void foo(short, short); // 2
void bar() {
foo(0, 1); // calls first overload
}
https://godbolt.org/z/E8zME93cc
Is this a defect in the standard?
Cheers,
Lénárd
[over.best.ics.general]:
"Implicit conversion sequences are concerned only with the type,
cv-qualification, and value category of the argument and how these are
converted to match the corresponding properties of the parameter."
https://timsong-cpp.github.io/cppwp/n4868/over.match#over.best.ics.general-2
My reading is that the intent of this paragraph is to specify that
viable and best viable functions are selected based on only type + cv +
value category of arguments, and disregard any other property. (This
probably only applies to expression arguments, as initializer list
arguments have non of these properties, but this is just a tangent.)
One example is that a call like `foo(some_obj.bit_field)` could find
`foo(int&)` as viable, and later become ill-formed if this turns out to
be the best viable function for the call.
However this same paragraphs rules out to consider whether the argument
is a null-pointer constant or not. Based on this a call like `foo(0)`
shouldn't find `foo(void *)` viable, as there is no implicit conversion
sequence from a prvalue of type int to `void *`,
Major compilers treat conversion from null-pointer constant to a
pointer type to an implicit conversion sequence and find viable
functions based on that (since forever, AFAIK).
void foo(void *, int); // 1
void foo(short, short); // 2
void bar() {
foo(0, 1); // calls first overload
}
https://godbolt.org/z/E8zME93cc
Is this a defect in the standard?
Cheers,
Lénárd
Received on 2023-01-07 21:16:53