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".
>
> 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