我喜欢在我的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; },
}
4条答案
按热度按时间q8l4jmvw1#
optional<T>
是T
和nothessness的非对称类型安全联合(nullopt_t
)。您可以查询它是否具有explicit operator bool
的T
,并使用一元*
得出T
。不对称意味着可选的"首选"为T
,这就是为什么非限定操作(如*
或运算符bool)引用它的T
属性。variant<A,B,C>
from paper n4218是A
、B
和C
等的对称型安全并集。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
相比,参数的顺序交换了)。pdtvr36n2#
你正在寻找的正是Alexandrescu的期望。我建议听他的演讲,以深入了解:https://www.youtube.com/watch?v=kaI4R0Ng4E8 .他实际上是一行一行地通过实现,你可以很容易地自己写,并在那之后很好地使用它。
Variant是一个更通用的工具,它可以被强制去做你想做的事情,但是你最好使用expected。
kkbh8khc3#
如果不仅仅是boost,你可以使用result。这是一个很好的单头容器。
8aqjt8rx4#
optional
在设计上要么包含某种类型的值,要么什么都不包含。您可能正在寻找类似
Boost::Variant
的内容。这还不是标准库的一部分,尽管类似的东西最终可能会成为标准库的一部分。