Date: Sun, 8 Jan 2023 23:56:14 +0100
> ... because literal 0 and literal 1 have the same type, cv and value category.
I agree in that point.
> So `foo(0, 1)` would be expected to behave the same as `foo(1, 1)`.
I don’t think so.
[over.best.ics.general/2] states: "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.**" (emphasis mine). In my understanding, the term „concerned“ means that other (restricting) properties might not affect the fact whether there is a valid conversion from one type into another. But it does not state that the conversion itself is limited to or determined just and only by „the type, cv-qualification, and value category“ - especially since the rules for the conversion itself are described in a completely different section [conv].
So, regarding the „implicit conversion sequences“, they are „concerned“ whether there is (at all) any legit conversion based on the type, cv-qualification, and value category of arguments and parameters. But the conversion itself is not limited, restricted, or „ concerned only with the type, cv-qualification, and value category“.
Going back to the example, this means the „implicit conversion sequences“ are „concerned“:
- for the first argument: from `cv-unqualified prvalue int` to `cv-unqualified lvalue void*` (overload 1) or from `cv-unqualified prvalue int` to `cv-unqualified lvalue short` (overload 2), respectively.
- for the second argument: from `cv-unqualified prvalue int` to `cv-unqualified lvalue int` (overload 1) or from `cv-unqualified prvalue int` to `cv-unqualified lvalue short` (overload 2), respectively.
It is not concerned whether the respective values are accessible or the like, it just cares about whether there is a potentially legit implicit conversion available „from -> to“.
So back to the first argument, for the first overload (1), it happens that there is indeed a legit implicit conversion available from `cv-unqualified prvalue int` to `cv-unqualified lvalue void*`. That is the „Pointer conversion“ - which happens to be available due to [conv.ptr/1]. But that conversion itself is in now way limited by or even related to [over.best.ics.general/2]. The pointer conversion has rank „Conversion“.
For the second overload (2), there is no need for an implicit conversion from `cv-unqualified prvalue int` to `cv-unqualified lvalue int`, since it is of category „Identity“ and has rank „Exact Match“.
At this point, the second overload (2) is only just the more viable overload.
Now, the second argument is evaluated.
For the first overload (1), there is a legit implicit conversion available from `cv-unqualified prvalue int` to `cv-unqualified lvalue short`. That is the „Integral conversion“ with rank „Conversion“.
For the second overload (2), there is a legit implicit conversion available from `cv-unqualified prvalue int` to `cv-unqualified lvalue short`. That is the „Integral conversion“ with rank „Conversion“.
So, at the end of the day, we have:
- for overload (1): Conversion-Exakt
- for overload (2): Conversion-Conversion
So, overload (1) is the „winner“ and more viable.
So again, in my understanding of the current wording, the conversion itself is in now way limited by or even related to [over.best.ics.general/2]. I think this paragraph is just there - as the related note suggests - to make it clear that the viability does not depend on whether the values are accessible or other properties, but just whether there is a known and legit implicit conversion from one (type, cv-qualification, and value category) „tuple“ into another.
Again, maybe I still miss the point but I don’t see any problem with the wording regarding how nullpointers are handled according to the specification. It is all clear in my understanding. Hope I could project my view somehow understandable.
Kind Regards
> ... because literal 0 and literal 1 have the same type, cv and value category.
I agree in that point.
> So `foo(0, 1)` would be expected to behave the same as `foo(1, 1)`.
I don’t think so.
[over.best.ics.general/2] states: "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.**" (emphasis mine). In my understanding, the term „concerned“ means that other (restricting) properties might not affect the fact whether there is a valid conversion from one type into another. But it does not state that the conversion itself is limited to or determined just and only by „the type, cv-qualification, and value category“ - especially since the rules for the conversion itself are described in a completely different section [conv].
So, regarding the „implicit conversion sequences“, they are „concerned“ whether there is (at all) any legit conversion based on the type, cv-qualification, and value category of arguments and parameters. But the conversion itself is not limited, restricted, or „ concerned only with the type, cv-qualification, and value category“.
Going back to the example, this means the „implicit conversion sequences“ are „concerned“:
- for the first argument: from `cv-unqualified prvalue int` to `cv-unqualified lvalue void*` (overload 1) or from `cv-unqualified prvalue int` to `cv-unqualified lvalue short` (overload 2), respectively.
- for the second argument: from `cv-unqualified prvalue int` to `cv-unqualified lvalue int` (overload 1) or from `cv-unqualified prvalue int` to `cv-unqualified lvalue short` (overload 2), respectively.
It is not concerned whether the respective values are accessible or the like, it just cares about whether there is a potentially legit implicit conversion available „from -> to“.
So back to the first argument, for the first overload (1), it happens that there is indeed a legit implicit conversion available from `cv-unqualified prvalue int` to `cv-unqualified lvalue void*`. That is the „Pointer conversion“ - which happens to be available due to [conv.ptr/1]. But that conversion itself is in now way limited by or even related to [over.best.ics.general/2]. The pointer conversion has rank „Conversion“.
For the second overload (2), there is no need for an implicit conversion from `cv-unqualified prvalue int` to `cv-unqualified lvalue int`, since it is of category „Identity“ and has rank „Exact Match“.
At this point, the second overload (2) is only just the more viable overload.
Now, the second argument is evaluated.
For the first overload (1), there is a legit implicit conversion available from `cv-unqualified prvalue int` to `cv-unqualified lvalue short`. That is the „Integral conversion“ with rank „Conversion“.
For the second overload (2), there is a legit implicit conversion available from `cv-unqualified prvalue int` to `cv-unqualified lvalue short`. That is the „Integral conversion“ with rank „Conversion“.
So, at the end of the day, we have:
- for overload (1): Conversion-Exakt
- for overload (2): Conversion-Conversion
So, overload (1) is the „winner“ and more viable.
So again, in my understanding of the current wording, the conversion itself is in now way limited by or even related to [over.best.ics.general/2]. I think this paragraph is just there - as the related note suggests - to make it clear that the viability does not depend on whether the values are accessible or other properties, but just whether there is a known and legit implicit conversion from one (type, cv-qualification, and value category) „tuple“ into another.
Again, maybe I still miss the point but I don’t see any problem with the wording regarding how nullpointers are handled according to the specification. It is all clear in my understanding. Hope I could project my view somehow understandable.
Kind Regards
Received on 2023-01-08 22:56:29