c++c++17variant

Unsafe, `noexcept` and no-overhead way of accessing `std::variant`


std::variant provides the following access functions:


I want an unsafe access function that:

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?


Solution

  • As pointed out by @T.C. in the comments, your first and third desiderata are mutually incompatible. This was spelled out in N3279, titled "Conservative use of noexcept in the Library".

    There are essentially two classes of contracts: narrow and wide. A wide contract for a function or operation does not specify any undefined behavior. Such a contract has no preconditions. Only functions with wide contracts are marked noexcept in the Standard Library.

    OTOH, a narrow contract is a contract which is not wide. Narrow contracts for a functions or operations result in undefined behavior when called in a manner that violates the documented contract. They cannot be marked noexcept. Instead, the best you can expect is that they are documented as "Throws: Nothing."

    It appears that you are out of luck and no such unchecked access is provided in the current proposals for std::variant.