C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Making the converting constructor of std::optional less greedy

From: Edward Catmur <ecatmur_at_[hidden]>
Date: Sun, 24 Dec 2023 17:19:17 -0600
On Wed, 20 Dec 2023 at 02:55, Egor via Std-Proposals <
std-proposals_at_[hidden]> wrote:

>
> 19.12.2023 07:07, Edward Catmur пишет:
>
>
>
> On Sat, 9 Dec 2023 at 01:13, Egor via Std-Proposals <
> std-proposals_at_[hidden]> 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>>()
}

Received on 2023-12-24 23:19:30