gpt4 book ai didi

c++ - noexcept 访问 std::variant

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:14:16 24 4
gpt4 key购买 nike

对于某些标准库类,访问其部分内容可能会合法地失败。通常,您可以在一些可能引发异常的方法和标记为 noexcept 的方法之间进行选择。后者省去了前提条件的检查,所以如果你想自己承担责任,你可以。这可以在不允许使用异常或修复性能瓶颈的情况下使用。

示例 1:std::vector元素访问:

std::vector<int> vec;
vec.at(n) // throws std::out_of_range
vec[n] // potentially UB, thus your own responsibility

示例 2:std::optional访问:

std::optional<int> optn;
optn.value() // throws std::bad_optional_access
*optn // potentially UB, thus your own responsibility

现在转到 std::variant .直接访问替代方案有点遵循这种模式:

std::variant<std::string, int> var;
std::get<int>(var) // potentially throwing std::bad_variant_access
*std::get_if<int>(&var) // potentially UB, thus your own responsibility

但是这次签名改变了,我们必须注入(inject)*&。这样做的缺点是我们没有自动移动语义。还有一件事要记住……

但如果你看一下 std::visit(Visitor&& vis, Variants&&... vars),情况会变得更糟.它没有 noexcept 替代方案,尽管它只会抛出

if any variant in vars is valueless_by_exception.

这意味着对于访问变体,您不能选择自己承担责任,如果您别无选择并且必须避免异常,则您根本无法使用标准工具访问 std::variants! (除了在 variant::index() 上使用 switch 的糟糕解决方法)

对我来说,这看起来像是一个非常糟糕的设计疏忽……或者这是有原因的?如果我对监督的看法是正确的,是否有计划在标准中解决这个问题?

最佳答案

This means for visiting variants you cannot choose to take the responsibility yourself

当然可以。如果您将值分配或放置到现有的 variant 中,则“异常无值”状态只会发生。此外,根据定义,只有在这些过程中实际抛出异常时才会发生。这不是随机 variant 刚刚发生的状态。

如果您有责任确保您永远不会放置/分配给变体,或者您使用的类型永远不会在这些情况下抛出,或者您以这样的方式响应任何异常,即 variant引发它没有被交谈(即:如果抛出 bad_alloc,您的应用程序不会捕获它;它只是关闭),那么您不必关心这种可能性。

基本上,如果您已经编码以避免异常,则 noexcept 的非 visit 状态是无关紧要的。除非抛出异常,否则 variant 永远不会进入“无值异常”。

关于c++ - noexcept 访问 std::variant,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53946674/

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