std::execution 是 C++26 中的空占位符命名空间,不提供任何实体;执行策略如 par_unseq 实际定义在 <algorithm> 的内联命名空间中,需包含该头文件且依赖未完成的库实现。

std::execution 是个空命名空间,C++26 里它不提供任何可调用的东西
别在代码里写 std::execution::unseq 或试图 using namespace std::execution——C++26 标准草案里 std::execution 纯粹是占位符,没有定义任何策略枚举、函数或类型。真正承载执行策略的是 std::execution::par_unseq 这类东西,但它们属于 <algorithm> 头文件里的内联命名空间(比如 std::execution::par_unseq 实际是 std::execution::parallel_unsequenced_policy 的别名),不是靠 std::execution 本身导出的。
常见错误现象:error: 'execution' is not a namespace of 'std' 或链接时报 undefined reference to 'std::execution::...' ,本质是头文件没包含、标准库实现未完成,或误把提案文档当实装。
- 必须包含
<algorithm>(而非<execution>,后者在 C++26 中仍不存在) - 只对标准算法生效,比如
std::sort(std::execution::par, ...),不能用于自定义异步逻辑 - libstdc++(GCC)和 libc++(Clang)目前均未完整实现 C++26 execution 策略,MSVC 也仅支持极简子集;实际项目中基本不可用
sender/receiver 不是 std::execution 的一部分,它是独立的 async 模型
std::sender 和 std::receiver 是 C++26 引入的**概念(concepts)**,定义在 <sender> 头文件中(注意:该头文件尚未被所有标准库实现提供)。它们和 std::execution 命名空间无继承、无依赖关系——一个管并行算法调度,一个管异步操作建模。
使用场景:你想写非阻塞 I/O、定时器、协程桥接、或自定义调度器链路时,才需要 sender/receiver;普通多线程循环加速不用碰它。
立即学习“C++免费学习笔记(深入)”;
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- receiver 必须实现
set_value/set_error/set_done三个定制点,缺一不可 - sender 不是类模板,而是一组要求满足 concept 的类型;
std::just(42)返回 sender,但你不能直接 new 它或继承它 - 连接 sender 和 receiver 要靠
connect+start两步,漏掉start就什么都不会发生——这是最常被忽略的死区
当前阶段怎么写出能跑的 sender/receiver 示例
别指望用 GCC 13 或 Clang 17 直接编译标准草案代码。可行路径只有两条:用 async_cpp_2023(Bryce Lelbach 的实验库),或等 libc++ 19+ / libstdc++ 14+ 正式发布支持。下面是以 async_cpp_2023 为基础的最小可运行片段:
#include <async_cpp_2023/sender.hpp>
#include <async_cpp_2023/scheduler.hpp>
#include <async_cpp_2023/just.hpp>
#include <iostream>
struct my_receiver {
void set_value(int x) { std::cout << "got: " << x << "\n"; }
void set_error(std::exception_ptr) {}
void set_done() {}
};
int main() {
auto s = async_cpp_2023::just(123);
auto op = async_cpp_2023::connect(s, my_receiver{});
async_cpp_2023::start(op); // 必须调!
}
关键点:
- 所有 sender 操作(
just、then、upon_error)都来自第三方库,不是标准头文件 -
connect返回的是 operation state,不是 future,也不能用auto推导后丢弃——它持有资源,析构会取消操作 - receiver 的
set_error必须接收std::exception_ptr,传int或std::string会编译失败
为什么现在就学 sender/receiver 容易白忙活
因为标准细节还在剧烈变动:C++26 最终稿可能调整 std::sender 的约束条件、重命名 set_stopped 为 set_done、甚至合并 scheduler 和 sender 接口。libc++ 提交记录显示,他们上周刚 revert 了三处 receiver concept 实现,理由是“与最新草案不兼容”。
更现实的问题是调试体验:gdb 几乎无法展开 sender 链,clangd 不识别 std::sender concept,编译错误信息动辄 200 行模板堆栈,且全指向库内部而非你的 receiver 实现。
- 除非你在参与 libc++/libstdc++ 开发,或公司基线已锁定 C++26 TS 工具链,否则建议暂缓落地
- 替代方案更稳:用
std::jthread+std::stop_token做可取消异步任务,或用std::coroutine_handle手写轻量 awaiter - receiver 的生命周期管理是隐式强耦合的——你得确保 receiver 在 operation state 析构前一直有效,这点比
std::future难控得多

















