On Tue, 10 Jan 2023 at 17:05, Brian Bi <bbi5291@gmail.com> wrote:


On Tue, Jan 10, 2023 at 11:24 AM Edward Catmur via Std-Discussion <std-discussion@lists.isocpp.org> wrote:


On Tue, 10 Jan 2023 at 15:57, language.lawyer--- via Std-Discussion <std-discussion@lists.isocpp.org> wrote:
> I would like an example of a function call to an overloaded function,
> where the most viable function is determined by the rules listed from
> [over.ics.rank]/4.4.5 to [over.ics.rank]/4.4.8:
>
> https://timsong-cpp.github.io/cppwp/n4868/over.ics.rank#4.4.5
>
> These are four different tie-breakers for ranking standard conversions
> from different source types, assuming the following class hierarchy:
>
> struct A {}; struct B : C {}; struct C : B {};
>
> (4.4.5) conversion of B* to A* is better than conversion of C* to A*,
> (4.4.6) binding of an expression of type B to a reference to type A is
> better than binding an expression of type C to a reference to type A,
> (4.4.7) conversion of B::* to C::* is better than conversion of
> A::* to C::*, and
> (4.4.8) conversion of B to A is better than conversion of C to A.
>
> The note says that these are only used for tie-breakers in the second
> conversion sequence of user-defined conversions:
>
> https://timsong-cpp.github.io/cppwp/n4868/over.ics.rank#note-1

I think it is just a wrong Note.
CD2 (November 96 https://www.open-std.org/jtc1/sc22/wg21/docs/wp/html/cd2/over.html#over.ics.rank) Note was saying:
> [Note:  it is necessary to compare conversions with different target
> types in the context of an initialization  by  user-defined  conver-
> sion; see _over.match.best_.  ]

Which also seems not 100% correct (incomplete?), because it mentions (only?) target, and not source types.

The next WP (Oct'97 https://www.open-std.org/jtc1/sc22/wg21/docs/wp/html/oct97/over.html#over.ics.rank) Note gained its current (defective) wording.

(The bullets themselves have been added by https://www.open-std.org/JTC1/sc22/wg21/docs/papers/1995/N0661.asc)

So, ecatmur's example seems to be relevant here, except that the Note is not about the second standard conversion sequence after different user conversion functions, but about https://timsong-cpp.github.io/cppwp/n4868/over.match.best#general-2.2

Ah. So, currently, the Note says:

> Compared conversion sequences will have different source types only in the context of comparing the second standard conversion sequence of an initialization by user-defined conversion (see [over.match.best]); in all other contexts, the source types will be the same and the target types will be different.

Whereas [over.match.best.general]/2.2 says:

> ... the context is an initialization by user-defined conversion (see [dcl.init], [over.match.conv], and [over.match.ref]) and the standard conversion sequence from the return type of F1 to the destination type (i.e., the type of the entity being initialized) is a better conversion sequence than the standard conversion sequence from the return type of F2 to the destination type ...

Would it make sense to amend the latter to mention the second SCS? i.e.,

> ... the context is an initialization by user-defined conversion (see [dcl.init], [over.match.conv], and [over.match.ref]) and the <ins>second</ins> standard conversion sequence <ins>of ICSj(F1) (i.e., that</ins> from the return type of F1 to the <del>destination type (i.e.,</del> the type of the entity being initialized) is a better conversion sequence than the <ins>second</ins> standard conversion sequence <del>from the return type of F2 to the destination type</del><ins>of ICSj(F2)</ins> ...

I think if we need to clarify it, we should just add a note. Changing normative wording always risks unforeseen consequences.

Ah, Well, should we change the offending Note (to [over.ics.rank]) then?

>  Compared conversion sequences will have different source types only in the context of <del>comparing the second standard conversion sequence of</del> an initialization by user-defined conversion<ins>, specifically when comparing the standard conversion sequence from the return type of a viable function to the destination type</ins> (see [over.match.best]); in all other contexts, the source types will be the same and the target types will be different.