C++相当于Rust的Result <T,E>类型?

Pet*_*yas 15 c++ boost optional c++17

我喜欢在我的C++代码中使用std :: experimental :: optional,但问题是value_or要求默认值与可选的值相同.

当我想要一个包含int或包含错误消息的可选项时,这不能很好地工作.

我想我可以使用一个带有布尔值的联合结构来指示该值是否存在或者它是一个错误,但如果C++只有Result<T, E>类似Rust 的类型,那肯定会很好.

有这样的类型吗?Boost为什么没有实现呢?

结果确实比Option更有用,Boost的人们肯定知道它的存在.也许我会去阅读Rust实现,然后将其复制到C++?

例如:

// Function either returns a file descriptor for a listening socket or fails
// and returns a nullopt value.
// My issue: error messages are distributed via perror.
std::experimental::optional<int> get_tcp_listener(const char *ip_and_port);
// You can use value_or to handle error, but the error message isn't included!
// I have to write my own error logger that is contained within
// get_tcp_listener. I would really appreciate if it returned the error
// message on failure, rather than an error value.
int fd = get_tcp_listener("127.0.0.1:9123").value_or(-1);
// Rust has a type which does what I'm talking about:
let fd = match get_tcp_listener("127.0.0.1:9123") {
    Ok(fd) => fd,
    Err(msg) => { log_error(msg); return; },
}
Run Code Online (Sandbox Code Playgroud)

Yak*_*ont 21

optional<T>是一种不对称类型的安全联盟T和虚无(nullopt_t).您可以查询它是否具有Twith explicit operator bool,并T使用unary获取*.不对称意味着可选的"更喜欢"为a T,这就是为什么不合格的操作(如*或操作符bool)引用它的原因T.

variant<A,B,C>从纸n4218是的对称型安全联盟A,BC(等). boost::variant总是啮合,std::experimental::variant几乎总是占线.

因为它是对称的,所以没有唯一的类型可供一元一行*返回,并且explicit operator bool不能说太多兴趣,所以都不支持.

相反,您必须访问它,或查询特定类型.

std::experimental::expected<E, T>来自paper n4015是一种不对称的类型安全联盟.它是a T或者a E.但是,就像optional,它"更喜欢"成为一个T; 它有一个explicit operator bool告诉你它是否是一个T,并且一元*获得了T.

从某种意义上说,expected<E,T>是一个optional<T>,但是当它是空的而不是浪费它存储的空间E,你可以查询.

Result<T,E>似乎接近expected<E,T>(注意,从n4015开始,参数的顺序相互交换Result).


Nir*_*man 8

您正在寻找的正是Alexandrescu的预期.我建议听他的演讲深入了解:https://channel9.msdn.com/Shows/Going+Deep/C-and-Beyond-2012-Andrei-Alexandrescu-Systematic-Error-Handling-in-C.他实际上逐行完成了实现,您可以轻松地自己编写并在此之后使用它.

Variant是一个更通用的工具,它可以被强制做你想做的事情但你最好的预期.


S.R*_*S.R 6

如果不仅涉及 boost ,你可以使用result。这是一个不错的单头容器。