C++ Logo

std-proposals

Advanced search

Re: [std-proposals] New method 'common_base' for 'std::variant'

From: Edward Catmur <ecatmur_at_[hidden]>
Date: Wed, 7 Sep 2022 16:50:41 +0100
On Wed, 7 Sept 2022 at 16:30, Arthur O'Dwyer via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> On Tue, Sep 6, 2022 at 1:34 PM Zhihao Yuan <zy_at_[hidden]> wrote:
>
>> On Tuesday, September 6th, 2022 at 7:25 AM, Arthur O'Dwyer via
>> Std-Proposals <std-proposals_at_[hidden]> wrote:
>>
>> This is just std::visit. Here's the "very simple" version using the Null
>> Object pattern (i.e., creating a new dummy subclass of IRS232 to represent
>> "no connection"):
>> https://godbolt.org/z/rEW6aq744
>> And here's the "less simple" version:
>> https://godbolt.org/z/h1rjzxGKG
>>
>> There are other ways to do it too, but std::visit seems like the simplest
>> — and it's already present in C++17.
>>
>> The logic is true, while the point of
>> this proposal was probably to allow
>> variant to return a pointer to its
>> own buffer without breaking the
>> type system.
>>
>
> My suggested use of `std::visit` doesn't "break the type system" as far as
> I can tell.
>

I conjecture that what ZY meant by this was that the implementation can
bypass the overhead of switching on the index, forming a pointer to the
derived object, and casting that to the base type, instead just forming a
pointer to the base type directly from the buffer (assuming of course that
the base type is indeed the first base and so has the same address in each
alternative), while not resulting in UB from an invalid pointer cast.

But a modern implementation can eliminate the overhead anyway by looking
through the call to std::visit; https://godbolt.org/z/a6o46TTbE compiles to
an unimpeachable:

f(std::variant<std::monostate, D1, D2>&):
        xor eax, eax
        cmp BYTE PTR [rdi+1], 0
        cmovne rax, rdi
        ret

Received on 2022-09-07 15:50:55