我喜欢在我的 C++ 代码中使用 std::experimental::optional,但问题是 value_or 要求默认值与可选值的类型相同。
当我想要一个包含 int 或包含错误消息的可选项时,这不会很好。
我想我可以使用一个带有 bool 值的 union 结构来指示该值是否存在或者它是一个错误,但如果 C++ 有一个 Result<T, E>
肯定会很好。像 Rust 这样的类型。
有没有这样的类型?为什么 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; },
}
最佳答案
optional<T>
是 T
的非对称类型安全 union 和虚无(nullopt_t
)。可以查询是否有T
与 explicit operator bool
,并获取 T
出一元*
.不对称意味着可选的“更喜欢”是 T
,这就是为什么不合格的操作(如 *
或 operator bool)引用它的 T
尼斯。</p>
variant<A,B,C>
from paper n4218是 A
的对称类型安全 union , B
和 C
(ETC)。 boost::variant
始终参与,std::experimental::variant
几乎一直在忙碌。
由于它是对称的,所以一元 *
没有唯一类型返回,和 explicit operator bool
不能说太多兴趣,所以都不支持。
相反,您必须访问它,或查询它的特定类型。
std::experimental::expected<E, T>
from paper n4015是一个非对称类型安全 union 。它是 T
, 或 E
.但是像 optional
,它“更喜欢”成为 T
;它有一个 explicit operator bool
告诉你它是否是 T
, 和一元 *
获取 T
.
从某种意义上说,expected<E,T>
是 optional<T>
,但是当它为空而不是浪费空间时,它存储了 E
,您可以查询。
Result<T,E>
似乎接近 expected<E,T>
(请注意,从 n4015 开始,与 Result
相比,参数的顺序交换了。
关于C++ 等价于 Rust 的 Result<T, E> 类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32126613/