std::variant
provides the following access functions:
std::get_if
: take pointer tovariant
, return pointer to alternative.template <std::size_t I, typename... Ts> auto* std::get_if(std::variant<Ts...>* pv) noexcept;
If
pv
is not a null pointer andpv->index() == I
, returns a pointer to the value stored in the variant pointed to bypv
. Otherwise, returns a null pointer value.This means that
get_if
's implementation roughly looks like this:template <std::size_t I, typename... Ts> auto* std::get_if(std::variant<Ts...>* pv) noexcept { if(pv == nullptr) return nullptr; if(pv->index() != I) return nullptr; return &(pv->real_get<I>()); }
std::get
: take reference tovariant
, return reference to alternative,throw
on invalid access.template <std::size_t I, typename... Ts> auto& std::get(std::variant<Ts...>& v);
If
v.index() == I
, returns a reference to the value stored inv
. Otherwise, throwsstd::bad_variant_access
.This means that
get
's implementation roughly looks like this:template <std::size_t I, typename... Ts> auto& std::get(std::variant<Ts...>& v) { if(v.index() != I) throw std::bad_variant_access{}; return v.real_get<I>(); }
I want an unsafe access function that:
Is
noexcept
.Takes a reference to a
variant
, avoiding anypv == nullptr
check.Has undefined behavior if
v.index() != I
.
Why? Because there may be some situations where I am 100% sure that a particular variant
instance contains a specific type in a code path. Also, it would be useful when writing generic code that already separately checked v.index() != I
(e.g. writing my own visit
).
Example implementation:
template <std::size_t I, typename... Ts>
auto& unsafe_get(std::variant<Ts...>& v)
{
return v.real_get<I>();
}
Is there something like this in the standard? I couldn't find it. If not, is this possible to implement for std::variant
, or do I need to roll out my own variant
implementation?
noexcept
on things that can lead to UB, so #1 and #3 are de facto mutually exclusive. – Freiman*std::get_if<I>(&my_variant)
cannot be optimized down to what you want, in principle. – FreimanI
matches the current index. There's no way to statically know that for any particularmy_variant
. – Koval