我们如何通过调用堆栈转发失败的 std::expected

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

我有一个像这样的

std::expected
用例:

class MyClass {
public:
    enum class error {
        e1 // ...
    };

    using index_return_type = std::expected<unsigned, error>;

    index_return_type add_data(data d);
    index_return_type update_data(data d);

    private:

    std::expected<void, error> expand_to_fit(data) {
        // Imagine i fail here
        return std::unexpected{error::e1};
    }
};

add_data
update_data
中,我总是会立即致电
expand_to_fit
,这可能会失败。如果确实如此,基本上错误已经存在,所以我只想将其推送到外部。我想出的最好的办法是:

index_return_type add_data(data d) {
    if (auto it_fit = expand_to_fit(d); !it_fit) {
        return std::unexpected{it_fit.error()};
    }
    // The rest of the function
}

但我不喜欢它。

  1. it_fit
    的命名是随意的,如果能装,但是
    expand_to_fit
    功能因为其他原因失败了怎么办?这使得这段代码难以阅读(并且有点欺骗性)。
  2. 这个小检查的人体工程学似乎有点粗糙,必须写满代码,并且在我看来,这使得代码更难阅读。

是否有更好的方法来通过调用函数转发失败的 std::expected ?

c++ error-handling c++23 std-expected
1个回答
0
投票

惯用的方法是使用一元成员操作之一:

  • and_then
    - 返回给定函数对期望值的结果(如果存在);否则,返回预期本身。

  • transform
    - 返回包含转换后的期望值(如果存在)的期望值;否则,返回预期本身

  • or_else
    - 如果包含预期值,则返回预期本身;否则,返回给定函数对意外值的结果

  • transform_error
    - 如果包含预期值,则返回预期本身;否则,返回包含转换后的意外值的预期

由于预期类型是

void
并且如果错误发生在
std::expected
内部,
expand_to_fit
将包含错误,因此您可以使用
transform
:

index_return_type add_data(data d) {
    return expand_to_fit(d).transform([&]{
        // the rest of the function wrapped inside a lambda
        return 0u;
    });
}
© www.soinside.com 2019 - 2024. All rights reserved.