gpt4 book ai didi

c++ - 不安全, `noexcept` 和访问 `std::variant` 的无开销方式

转载 作者:可可西里 更新时间:2023-11-01 15:22:20 24 4
gpt4 key购买 nike

std::variant提供以下访问功能:

  • std::get_if : 将 pointer 指向 variant,将 pointer 返回给 alternative。

    template <std::size_t I, typename... Ts> 
    auto* std::get_if(std::variant<Ts...>* pv) noexcept;
    • If pv is not a null pointer and pv->index() == I, returns a pointer to the value stored in the variant pointed to by pv. Otherwise, returns a null pointer value.

      这意味着 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 : referencevariant,返回 reference 到 alternative,throw 无效访问.

    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 in v. Otherwise, throws 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 检查。

  • 如果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 实现?

最佳答案

正如@T.C 所指出的。在评论中,您的第一个和第三个 desiderata 是互不相容的。这在 N3279 中有详细说明。 ,标题为“图书馆中 noexcept 的保守使用”。

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

OTOH, 契约(Contract)是不宽的契约(Contract)。当以违反记录契约的方式调用时,功能或操作的狭窄契约会导致未定义的行为。它们不能标记为 noexcept。相反,您可以期望的最好结果是它们被记录为“抛出:无”。

看起来你运气不好,在当前的 std::variant 提案中没有提供这种未经检查的访问。

关于c++ - 不安全, `noexcept` 和访问 `std::variant` 的无开销方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42052122/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com