On Tue, 26 Dec 2023 at 22:39, Egor via Std-Proposals <std-proposals@lists.isocpp.org> wrote:


25.12.2023 05:19, Edward Catmur пишет:

This won't always work. If the conversion operator is templated, it will receive the base class type, not the derived type, and the behavior for the two can be different (one of them can be rejected by SFINAE but not the other, etc).


It seems to work; am I missing something? https://godbolt.org/z/3c5fjnqo4

`std::is_convertible_v<const U&, secret_base<T>>` and `std::is_convertible_v<const U&, optional<T>>` are not equivalent. You could have arbitrary constraints on `A::operator T` that permit conversions to one and not the other.

That's the trick; A can't know about `secret_base<T>` (since it's secret), so it can't condition conversions on that type, and any conversion that reaches `optional<T>` can always be extended with a derived-to-base conversion.

If `A::operator T` constrains out `std::optional<U>` (and `std::in_place_t`), then the converting constructor of `std::optional<U>` won't accept `A`. But that is almost certainly what the user intended! https://godbolt.org/z/dzv68bWhG