C++ Logo

std-proposals

Advanced search

Re: std::variant - going from Alternative& to the enclosing variant&

From: Andreas Ringlstetter <andreas.ringlstetter_at_[hidden]>
Date: Fri, 11 Sep 2020 16:07:48 +0200
Victor Khomenko via Std-Proposals <std-proposals_at_[hidden]>:
> This is already explained in the original post - the risk of UB can be mitigated (but not eliminated) by checking that the supplied type is indeed a variant and that it contains the type of the argument as an alternative. Also, the requirement that the programmer must supply the variant type (rather than a list of types of alternatives) helps - the variants are likely to be typedef'ed, so one can just use the type synonym - this mitigates the problem of listing the types in the wrong order.

How about going back to looking for a pattern on the visitor which
doesn't require any form of potential UB (if used carelessly)?

    namespace std {
        template <size_t I>
        struct variant_tag final {
            static constexpr size_t index = I;
        }
    }
    using my_variant = std::variant<int, float>;

    struct visitor {
        void operator(my_variant &v, std::variant_tag<0> t) {
            auto& w = std::get<t.index>(v);
        }
        void operator(my_variant &v, std::variant_tag<1> t) {
            auto& w = std::get<t.index>(v);
        }
    }

No ambiguities, no aliasing, no overhead (assuming `std::get` gets
inlined), and all potential mis-use checked at compile time, with full
access to the variant.
Sacrifices a bit on readability by supporting index only, so maybe
optional tagging by type rather than index may make sense, but
otherwise it should cover all the discussed issues, shouldn't it?

Received on 2020-09-11 09:11:33