C ++相当于Rust的Result <t,e =“”>类型?

时间:2015-08-20 19:20:30

标签: c++ boost optional c++17

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

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

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

有这样的类型吗? 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; },
}

4 个答案:

答案 0 :(得分:19)

optional<T>T和虚无(nullopt_t)的非对称类型安全联合。您可以查询T是否包含explicit operator bool,并使用一元T获取*。不对称意味着可选的&#34;更喜欢&#34;成为T,这就是为什么不合格的操作(如*或操作符bool)引用其T的原因。

variant<A,B,C> from paper n4218ABC(等)的对称类型安全联合。始终使用boost::variantstd::experimental::variant几乎

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

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

std::experimental::expected<E, T> from paper n4015是一种不对称的类型安全联盟。它是TE。但就像optional一样,它更喜欢&#34;成为T;它有一个explicit operator bool,告诉您它是T还是一元*获得T

从某种意义上说,expected<E,T>optional<T>,但是当空白而不是浪费空间时,它会存储E,您可以查询。

Result<T,E>似乎接近expected<E,T>(请注意,从{n4015开始,与Result相比,参数的顺序是交换的。)

答案 1 :(得分:7)

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

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

答案 2 :(得分:3)

设计中的

optional要么包含某种类型的值,要么包含任何内容。

您可能正在寻找类似Boost::Variant的内容。

这还不是标准库的一部分,尽管最终可能会有类似的东西。

答案 3 :(得分:2)

如果不仅涉及提升,你可以使用result。这是一个很好的单头容器。