c++oding="utf-8" ?>
std::function无法存储捕获std::unique_ptr的lambda,因其要求copyconstructible而该lambda仅满足moveconstructible;std::move_only_function专为此设计,仅需moveconstructible且无拷贝开销。

不能用 std::function 存捕获 std::unique_ptr 的 lambda?那就必须用 std::move_only_function——它不是“更弱的 std::function”,而是唯一能合法收下这类 move-only callable 的标准容器。
为什么 std::function 编译失败,而 std::move_only_function 可以
根本原因是约束不同:std::function 要求目标类型满足 CopyConstructible,而捕获 std::unique_ptr 的 lambda 自动删除了拷贝构造函数;std::move_only_function 只要求 MoveConstructible,绕过该限制。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 典型错误信息:
error: use of deleted function 'X::X(const X&)',这不是你写错了,是语义不匹配 - 哪怕 lambda 声明为
const,只要内部移动了捕获对象(比如ptr.reset()),它就只能进std::move_only_function -
std::function无法从非空实例安全 move 出来(部分实现允许空实例 move,但不可靠);std::move_only_function显式设计为 move-first
声明和初始化时最容易漏掉的三件事
模板参数必须显式写出完整调用签名,且初始化必须用 std::move——这两点缺一不可,否则编译直接报错。
- 必须写全修饰符:
std::move_only_function<int const noexcept></int>,不能省略const或noexcept,否则operator()不匹配调用语境 - 不能隐式转换:
auto lam = [](){...}; std::move_only_function<void> f = lam;</void>❌ 编译失败;必须写成std::move_only_function<void> f = std::move(lam);</void>✅ - 没有
make_move_only_function辅助函数,也不能用auto推导类型——模板参数无法自动推导
往 vector 或作为函数参数传递时怎么避免崩溃
所有涉及所有权转移的地方,都必须显式调用 std::move。编译器不会帮你“悄悄 move”,也不会给你运行时机会——错就是编译错。
-
std::vector<:move_only_function>> tasks;</:move_only_function>→tasks.push_back(std::move(task));,写tasks.push_back(task)直接报错 - 函数参数建议用右值引用:
void enqueue(std::move_only_function<void> &&task)</void>,避免在入口就尝试拷贝 - 若封装为类成员,移动赋值操作符不能依赖默认生成(除非所有成员都支持移动),需手动定义为
= default或显式移动每个std::move_only_function成员
它真的“零开销”吗?别被 sizeof 欺骗
空 std::move_only_function 通常占 16 字节(两个指针),比 std::function 的 32 字节小,但这只是表象。关键差异在于它彻底删掉了拷贝逻辑所需的虚函数表项、引用计数、SBO 对齐填充和析构守卫。
- 小 callable(如捕获单个
std::unique_ptr的 lambda)可能原地构造,不触发堆分配;但一旦超过小缓冲区容量(libc++ 默认 24 字节,libstdc++ 通常 32 字节),仍会 fallback 到堆分配 - 它不提供
target()或target_type(),因为 move-only 类型擦除后无法安全还原原始类型——这点常被忽略,却直接影响调试和反射能力 - 别把它塞进需要
CopyConstructible的老接口(如某些第三方回调注册函数),编译不过就是不过,没商量余地
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










