如何在 C++ 中使用 std::optional

How to use std::optional in C++

在C++17中引入了std::optional,我很高兴这个决定,直到我看到了ref。我知道 Optional/Maybe 来自 Scala,Haskell 和 Java 8,其中 optional 是一个 monad 并遵循 monadic 法则。 C++17 实现中不是这种情况。如果没有像 mapflatMap/bind 这样的函数,我应该如何使用 std::optional,使用 std::optional 与返回 [=19] 相比有什么优势=],或者函数计算结果失败时的 nullptr? 对我来说更重要的是,为什么 std::optional 没有设计成 monad,有什么原因吗?

How am I supposed to use std::optional, whithout functions like map and flatMap/bind

Maybe in Haskell 在没有 fmap 的情况下完全可用,它代表一个可能存在或可能不存在的值。它还为类型系统带来了区别,因此您需要处理这两种情况。

whats the advantage using a std::optional vs for example returning -1, or a nullptr from a function if it fails to compute a result?

你怎么知道错误情况是什么?是 0-1MAX_INTnullptr 还是其他?如果我同时拥有 unsigned intint return 值以及之前 return 编辑 -1int 版本,您是否应该将它们都更改为 MAX_INT 或者让它们 return 不同的值? std::optional 避免了这个问题。

And more important for me, why wasn't std::optional designed to be a monad, is there a reason?

C++ 目前有 monad 吗?直到出现与容器不同的抽象,才真正有办法添加该功能。

可以 std::optional 上定义 bindreturn,所以在这个意义上它仍然是一个 Monad。

例如,一个可能的 bind

template<typename T1, typename T2>
std::optional<T2> bind(std::optional<T1> a, std::function< std::optional<T2>(T1)> f) {
   if(a.has_value()) return f(a.value());
   return std::optional<T2>{};
 }

定义这个实际上可能有用。

至于为什么标准库不附带这个或类似的东西,我认为答案是语言中的首选风格之一。

P0798r0 proposal with exactly this, and the associated implementation here on Github个。该提案还参考了通用的 monadic 接口提案,并且同样可用 std::expected。这些的实现也可用。