访问 std::variant 的不安全、`noexcept` 和无开销的方式

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

std::variant提供以下访问函数:


我想要一个不安全的访问函数:

为什么?因为在某些情况下,我可以 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 实施?

我认为您必须自己实现整个变体。 尽管不受限制的联合会有所帮助 - 它们至少解决了将多个类型放在同一位置并处理对齐问题的问题。

正如@T.C指出的那样。在评论中,您的第一个和第三个 desiderata 是互不相容的。这在 N3279 中有详细说明,标题为 "Conservative use of noexcept in the Library"。

基本上有两种 类 合同:窄合同和宽合同。函数或操作的 wide 契约不指定任何未定义的行为。 这样的合同没有先决条件。在标准库中,只有具有广泛契约的函数才被标记为 noexcept

OTOH,narrow 合约是一个不宽的合约。当以违反记录契约的方式调用时,函数或操作的狭窄契约会导致 未定义的行为 。它们不能被标记为 noexcept。相反,您可以期望的最好结果是它们被记录为 "Throws: Nothing."

看来您运气不好,std::variant 的当前提案中没有提供此类未经检查的访问权限。