C++ Logo

std-proposals

Advanced search

Re: [std-proposals] [DRAFT PAPER] std::variant with std::specify_base

From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Date: Thu, 15 Sep 2022 15:56:38 -0700
I still don't understand why Frederick wants any changes to the
existing std::variant. You can already do all of this today: given a
`variant<Cat, Dog>`, it's trivial to get an `Animal*` out of it using
`std::visit`. And you can even make your visitor return nullptr in the case
that you're given a `variant<Cat, Dog, Tree>` where the active alternative
happens to be `Tree`. Here's the code:

// https://godbolt.org/z/nbGda8h6K

template<class Base, class... Ts>
Base *specify_base(std::variant<Ts...>& v) {
return std::visit([](auto& t) -> Base* {
if constexpr (std::is_base_of_v<Base, std::decay_t<decltype(t)>>) {
return &t;
} else {
return nullptr;
}
}, v);
}

void test(std::variant<Cat, Dog, Tree> v) {
if (Animal *a = specify_base<Animal>(v)) {
a->speak();
} else {
std::cout << "trees don't speak\n";
}
}

On Thu, Sep 15, 2022 at 2:58 PM Frederick Virchanza Gotham via
Std-Proposals <std-proposals_at_[hidden]> wrote:

> On Thu, Sep 15, 2022 at 9:33 PM Zhihao Yuan <zy_at_[hidden]> wrote:
> >
> > I agree that variant<monostate, Cat, Dog>
> > can be a model for
> > variant<specify_base<Animal>, Cat, Dog>,
> > but I also want variant<Cat, Dog> to
> > implement an Animal interface.
> > To summarize, I think
> >
> > nonnull
> > nullable
> > throwing
> >
> > All make sense.
> >
> > How about this:
> >
> > template<class T>
> > struct implements
> > {
> > template<class... Ts>
> > using model = std::variant<Ts...>;
> > };
> >
> > template<class T>
> > struct implements_nullable
> > {
> > template<class... Ts>
> > using model = std::variant<std::monostate, Ts...>;
> >
> > static auto default_proxy() noexcept { return nullptr; }
> > };
> >
> > template<class T>
> > struct implements_or_throw
> > {
> > template<class... Ts>
> > using model = std::variant<std::monostate, Ts...>;
> > };
>
>
> It isn't immediately apparent to me how you would use those. Something
> like the following?
>
> implements<Animal>::model<Dog,Cat,Fish> obj;
>
> obj->Eat();
>
> The whole point of my proposal is to have this simple syntax:
> obj->BaseClassMethod();
>
> I want it to all be inside "std::variant" so that the object can be
> used in templates that expect an std::variant, and also so that the
> "std::variant" object can be copied and it will still retain all of
> its info (which wouldn't happen if we made a new class derived from
> "std::variant").
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2022-09-15 22:56:51