如何修改std::optional以通过C++协程实现Monad特性?
C++协程与std::optional适配的细节问题
搜索C++协程与std::optional相关内容时结果有限,从相关回答可推断:std::optional无法非侵入式适配以下协程,必须修改自身才能生效,现需明确具体细节:
目标协程代码
template<typename T> std::optional<T> plus(std::optional<T> a, std::optional<T> b) { co_return (co_await a) + (co_await b); }
期望满足的断言
assert(plus(std::make_optional(3), std::make_optional(4)) == std::make_optional(7)); assert(plus(std::make_optional(3), std::nullopt) == std::nullopt); assert(plus(std::nullopt, std::make_optional(4)) == std::nullopt);
核心疑问
std::optional在该协程中同时扮演三个角色:
- 协程返回类型
- co_await操作数(可等待对象)
- co_return值的容器
不确定哪些角色要求必须修改std::optional,尤其困惑角色1和3的协同逻辑:协程通过promise_type::get_return_object()返回的对象初始为空,而co_return需要修改该对象,但promise_type::return_value(auto v)该如何实现这一点?
非侵入式尝试的问题
尝试过非侵入式实现:为std::optional定义co_await运算符以提供自定义可等待对象,同时特化std::coroutine_traits,但发现计算结果无法存入返回的std::optional中——而这本该是return_value的职责。另外,Barry Revzin的提案提到std::expected可合规实现类似逻辑,但不确定是否无需修改std::expected本身。
内容的提问来源于stack exchange,提问作者Enlico
相关产品推荐
相关产品推荐

