On Wednesday, September 7th, 2022 at 8:50 AM, Edward Catmur <ecatmur@googlemail.com> wrote:
[...] 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
Yes, nice codegen. However, discussions
around design vs. QoI always come in two
folds:
// on top of the std::variant abstraction
a) it exposes a sound property (in this case,
the equivalency between a sum type and
a closed set of subtypes), and
it is a useful (in this case, adapt code that
relies on subtype polymorphism. You can
call v.common_base()->virtual_function()
as a transit).
or
// write it yourself
b) non-portable codegen is a QoI issue;
file a bug to your vendor (in this case,
clang & libc++ and msvc
quality of debug codegen is still QoI;
at worst, add some pragma.
I recommend writing a paper if you are
motivated.
--
Zhihao Yuan, ID lichray
The best way to predict the future is to invent it.
_______________________________________________