On Wed, 20 Dec 2023 at 02:55, Egor via Std-Proposals <std-proposals@lists.isocpp.org> wrote:


19.12.2023 07:07, Edward Catmur пишет:


On Sat, 9 Dec 2023 at 01:13, Egor via Std-Proposals <std-proposals@lists.isocpp.org> wrote:

07.12.2023 11:15, Egor пишет:

After thinking about it, I'm not sure this is even implementable in the
first place. This constraint would have to be self-referential, and I
think those are illegal.

It's quite easy, actually; all you have to do is test for convertibility to an arbitrary hypothetical unambiguous public base class of the class being constructed. This should be implementable without affecting ABI, I think.

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

#include <type_traits>
template<class T>
struct secret_base {}; // here
template<class T>
struct optional : secret_base<T> { // here
    template<class U>
    requires (std::is_constructible_v<T, const U&>) and (not (
        std::is_constructible_v<T, optional<U>&> /* or ... */))
        and (not std::is_convertible_v<const U&, secret_base<T>>) // here
    explicit(not std::is_convertible_v<const U&, T>)
    optional(U const&);
};
struct A {
    template<class T> operator T();
};
int main() {
    A a;
    optional<int> o(a); // calls A::operator optional<int><optional<int>>()
}