C++ Logo

std-proposals

Advanced search

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

From: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
Date: Fri, 9 Sep 2022 09:58:00 +0100
On Fri, Sep 9, 2022 at 12:15 AM Frederick Virchanza Gotham wrote:
>
> if constexpr ( std::is_same_v<U, std::monostate> )
> {
> return nullptr;
> }


One of greatest attractions in what I'm proposing is the ability to
use the following syntax:

    rs232.common_base<IR232>()->Close();

However . . . we of course don't want to invoke the "Close" method on
a nullptr if the currently hosted object is a 'monostate'.

Therefore I've edited the code to throw 'bad_variant_access' instead
of returning a nullptr, as follows:

    template<class Base>
    static Base const volatile
*detail_common_base(std::variant<Types...> const volatile *const arg)
    {
        std::variant<Types...> *const p = const_cast<
std::variant<Types...> * >(arg);

        auto my_lambda = []<class U>(U &u) -> Base*
          {
              if constexpr ( std::is_same_v<U, std::monostate> )
              {
                  throw std::bad_variant_access();
              }
              else
              {
                  static_assert( std::is_base_of_v<Base,U>,
                                 "Base class specified to
std::variant<Types...>::common_base() "
                                 "is not a base class of currently
hosted object" );

                  return &u;
              }
          };

        return std::visit<Base*>(my_lambda, *p);
    }

So now we can safely do:

    my_variant_object.common_base<IR232>()->Close();

inside a 'try' block, and we won't end up dereferencing a nullptr.

But maybe we could simplify the syntax even further by using a new
helper class "std::specify_base" as follows:

    std::variant< std::specify_base<Mammal>, Dog, Cat > my_mammal;

    my_mammal.common_base()->Speak();

The helper class "std::specify_base" would be similar to how we have
the likes of "std::in_place_t".

Received on 2022-09-09 08:58:12