我有一个像这样的
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
}
但我不喜欢它。
it_fit
的命名是随意的,如果能装,但是expand_to_fit
功能因为其他原因失败了怎么办?这使得这段代码难以阅读(并且有点欺骗性)。是否有更好的方法来通过调用函数转发失败的 std::expected ?
惯用的方法是使用一元成员操作之一:
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;
});
}