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?