我喜欢在我的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; },
}
答案 0 :(得分:19)
optional<T>
是T
和虚无(nullopt_t
)的非对称类型安全联合。您可以查询T
是否包含explicit operator bool
,并使用一元T
获取*
。不对称意味着可选的&#34;更喜欢&#34;成为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
一样,它更喜欢&#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)
答案 3 :(得分:2)
如果不仅涉及提升,你可以使用result。这是一个很好的单头容器。