std::move_only_function 是 C++23 引入的仅支持移动语义的函数包装器,用于封装 unique_ptr、mutex 等不可拷贝的可调用对象,满足 MoveConstructible/MoveAssignable 要求,不支持拷贝和 target 相关反射接口。
std::move_only_function 是 C++23 引入的新特性,用来替代传统 std::function 中“仅支持可复制”这一限制,专为**只可移动(move-only)的可调用对象**设计。它不强制要求底层可调用对象支持拷贝,因此能包装 lambda 捕获了 unique_ptr、fstream、mutex 或其他不可拷贝资源的闭包,也能包装 std::unique_ptr<:any_callable> 等 move-only 类型。
std::function 要求其模板参数 F 必须满足 CopyConstructible。这意味着:如果你写了一个捕获了 std::unique_ptr 的 lambda,它本身不可拷贝,就无法存入 std::function —— 编译直接失败。
而 std::move_only_function 只要求 MoveConstructible 和 MoveAssignable,彻底解除了拷贝约束,让 move-only 逻辑可以自然封装和传递。
它的模板形参和调用签名声明方式与 std::function 高度一致:
std::move_only_function,例如 std::move_only_function
.target()、.target_type() 等反射接口(因 move-only 存储通常需类型擦除 + 动态分配,元信息难保全)以下代码展示如何包装一个带 unique_ptr 捕获的 lambda:
auto make_move_only_task() {
auto ptr = std::make_unique(42);
// 此 lambda 不可拷贝(unique_ptr 不可拷贝)
return std::move_only_function{[ptr = std::move(ptr)]() mutable {
return *ptr;
}};
}
int main() {
auto f = make_move_only_task(); // OK: 移动构造
// auto f2 = f; // ❌ 编译错误:不可拷贝
auto f3 = std::move(f); // ✅ 合法:可移动
std::cout << f3() << "\n"; // 输出 42
}
再比如包装一个临时的 或自定义 move-only 函数对象,也都适用。
std::unique_ptr<:function>>
if (f),但调用前务必判空(和 std::function 一致)-std=c++23
它不是 std::function 的“升级版”,而是互补角色:需要拷贝时用 std::function,只需移动时用 move_only_function —— 更精准表达意图,也更安全。