You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何std::expected<void, Error>不支持monadic操作?

为何std::expected<void, Error>不支持monadic操作?

你遇到的问题其实不是C++标准的std::expected实现不完整,而是对void特化的expected的monadic操作(and_then/or_else)的使用规则理解有误——and_then和or_else要求传入的闭包必须返回另一个std::expected类型(可以是void特化的版本),而不是直接返回void。

我们先拆解你的代码问题:

std::expected<void, Error> fun (int);

fun (19).and_then ([]() { doSomething(); }).or_else ([] (Error e) { std::println ("Uh oh error.."); });

这里的and_then闭包[]() { doSomething(); }返回的是void,但and_then的设计逻辑是接收一个返回std::expected<...>的可调用对象——它需要延续expected的链式状态传递,直接返回void会打断这个状态链,所以触发了编译器的静态断言错误。

你看到的错误信息static assertion failed: std::__expected::__is_expected<void> evaluates to false就是最直接的提示:编译器期望闭包返回一个expected类型,但你给出的是void,完全不符合要求。

修正后的代码示例

要让这段代码正常工作,你需要让and_then和or_else的闭包都返回std::expected<void, Error>(或者兼容的expected类型),维持状态链的传递:

#include <expected>
#include <print>

enum class Error { OperationFailed };

std::expected<void, Error> fun(int val) {
    if (val == 19) return {}; // 成功:返回void特化的expected
    return std::unexpected(Error::OperationFailed);
}

void doSomething() {
    std::println("Executing doSomething...");
}

int main() {
    fun(19)
        .and_then([]() -> std::expected<void, Error> {
            doSomething();
            // 返回void特化的expected,表示当前步骤成功
            return {};
        })
        .or_else([](Error e) -> std::expected<void, Error> {
            std::println("Uh oh error encountered..");
            // 可选:继续传递错误,或返回成功终止链
            return std::unexpected(e);
        });
    return 0;
}

设计逻辑的本质

std::expected的monadic操作核心是链式状态传递:每个链式调用都需要返回一个expected来表示当前步骤的成功/失败状态,这样后续的调用才能基于这个状态继续执行。

哪怕是void特化的expected,它依然代表“成功无返回值”或“失败带错误”的状态,所以monadic操作要求闭包返回expected来维持这个状态链,而不是直接返回void打断链条。这不是标准的遗漏,而是monadic操作的本质要求——它要确保每一步都能把状态传递下去,而不是中途“断链”。

备注:内容来源于stack exchange,提问作者David

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 10:43:02