Rust的Result〈T,E>类型的C++等价物?

hgncfbus  于 2022-12-01  发布在  其他
关注(0)|答案(4)|浏览(204)

我喜欢在我的C代码中使用std::experimental::optional,但问题是value_or要求默认值与可选值的类型相同。
当我想要一个包含int或者包含错误消息的可选函数时,这就不太好用了。
我想我可以使用一个联合结构,它有一个布尔值来指示值是否存在或它是一个错误,但如果C
只有一个像Rust这样的Result<T, E>类型,那肯定会很好。
有没有这种类型?为什么Boost还没有实现?
Result确实比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; },
}
q8l4jmvw

q8l4jmvw1#

optional<T>T和nothessness的非对称类型安全联合(nullopt_t)。您可以查询它是否具有explicit operator boolT,并使用一元*得出T。不对称意味着可选的"首选"为T,这就是为什么非限定操作(如*或运算符bool)引用它的T属性。
variant<A,B,C> from paper n4218ABC等的对称型安全并集。boost::variant总是啮合,std::experimental::variant * 几乎 * 总是啮合。
因为它是对称的,所以一元*没有唯一的类型可返回,并且explicit operator bool也不能表达太多感兴趣的内容,因此两者都不受支持。
相反,您必须访问它,或查询它以获得特定类型。
std::experimental::expected<E, T> from paper n4015是一个不对称的类型安全联合。它要么是T,要么是E。但是像optional一样,它"更喜欢"是T;它有一个explicit operator bool,它告诉你它是否是T,一元*得到T
从某种意义上说,expected<E,T>是一个optional<T>,但是当它为空时,它存储了一个可以查询的E,而不是浪费空间。
Result<T,E>看起来与expected<E,T>很接近(注意,从n4015开始,与Result相比,参数的顺序交换了)。

pdtvr36n

pdtvr36n2#

你正在寻找的正是Alexandrescu的期望。我建议听他的演讲,以深入了解:https://www.youtube.com/watch?v=kaI4R0Ng4E8 .他实际上是一行一行地通过实现,你可以很容易地自己写,并在那之后很好地使用它。
Variant是一个更通用的工具,它可以被强制去做你想做的事情,但是你最好使用expected。

kkbh8khc

kkbh8khc3#

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

8aqjt8rx

8aqjt8rx4#

optional在设计上要么包含某种类型的值,要么什么都不包含。
您可能正在寻找类似Boost::Variant的内容。
这还不是标准库的一部分,尽管类似的东西最终可能会成为标准库的一部分。

相关问题