C++ Logo

std-proposals

Advanced search

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

From: Marcin Jaczewski <marcinjaczewski86_at_[hidden]>
Date: Fri, 11 Sep 2020 16:35:37 +0200
pt., 11 wrz 2020 o 16:08 Andreas Ringlstetter via Std-Proposals
<std-proposals_at_[hidden]> napisaƂ(a):
>
> 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?

When I start thinking about this, I think this could be a better solution.
The only thing I would change compared to your version is make
`std::variant_tag` callable.
This will allow use it in generic algorithms and simplify usage like:

```
         void operator(my_variant &v, std::variant_tag<1> t) {
             auto& w = t(v); // same as `std::get<t.index>(v);`
         }
```


> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

Received on 2020-09-11 09:39:19