unsafe,`noexcept`和无头的访问sTD ::variant`

问题描述 投票:0回答:1

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

std::bad_variant_access
,避免进行任何检查。

是否有未定义的行为

    为什么?因为在某些情况下,我100%确定特定的
  • 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

    实施,还是我需要推出自己的
  • variant
  • 实施?

    @ @T.C指出。在评论中,您的第一个和第三个Desiderata是相互不相容的。这是在

    N3279
中阐明的,标题为“库中的Noexcept的保守使用”。

基本上有两类合同:狭窄而宽。范围内的功能或操作合同未指定任何未定义的行为。
这样的合同没有前提条件。在标准库中仅标记具有广泛合同的功能。 
otoh,一份narrow
合同是一份不广泛的合同。当以违反已记录的合同的方式调用时,功能或操作的狭窄合同会导致未定义的行为
。它们不能被标记
v.index() != I
。取而代之的是,您可以期望的最好的是记录它们为“投掷:没有”。

似乎您很幸运,目前的

visit

提案中没有提供这样的不受欢迎的访问权限。
    

我认为您必须自己实施整个变体。 尽管不受限制的工会可能会有所帮助 - 他们至少解决了在同一位置将多种类型放置在同一位置的情况下。

no.
C ++标准确实可以保证变体代表一个联合,其数据必须在结构本身中保存:

...变体对象包含的值,分配在变体对象的存储中。实现不允许使用其他存储(例如动态内存)分配包含的值。
c++ c++17 variant
1个回答
7
投票
template <std::size_t I, typename... Ts> auto& unsafe_get(std::variant<Ts...>& v) { return v.real_get<I>(); }

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.