std::variant
предоставляет следующие функции доступа:
-
std::get_if
: возьмите указатель наvariant
, верните указатель на альтернативу.template <std::size_t I, typename... Ts> auto* std::get_if(std::variant<Ts...>* pv) noexcept;
-
Если
pv
не является нулевым указателем иpv->index() == I
, возвращает указатель на значение, сохраненное в варианте, на которое указываетpv
. В противном случае возвращает значение нулевого указателя.Это означает, что реализация
get_if
выглядит примерно так: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
: обратитесь кvariant
, верните ссылку на альтернативу,throw
на недопустимый доступ.template <std::size_t I, typename... Ts> auto& std::get(std::variant<Ts...>& v);
-
Если
v.index() == I
, возвращает ссылку на значение, хранящееся вv
. В противном случае выбрасываетсяstd::bad_variant_access
.Это означает, что реализация
get
выглядит примерно так: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>(); }
-
Я хочу функцию небезопасного доступа, которая:
-
Является
noexcept
. -
Делает ссылку на
variant
, избегая проверкиpv == nullptr
. -
Поведение undefined, если
v.index() != I
.
Почему? Потому что могут быть ситуации, когда я на 100% уверен, что конкретный экземпляр variant
содержит определенный тип кода. Кроме того, было бы полезно при написании общего кода, который уже отдельно проверен v.index() != I
(например, написания моего собственного visit
).
Пример реализации:
template <std::size_t I, typename... Ts>
auto& unsafe_get(std::variant<Ts...>& v)
{
return v.real_get<I>();
}
Есть ли что-то подобное в стандарте? Я не мог найти его. Если нет, можно реализовать для std::variant
, или мне нужно выполнить собственную реализацию variant
?