0

0

c++23 std::move_only_function怎么用 c++只能移动的函数包装器【详解】

冰火之心

冰火之心

发布时间:2025-12-29 17:25:23

|

111人浏览过

|

来源于php中文网

原创

std::move_only_function 是 C++23 引入的仅支持移动语义的函数包装器,用于封装 unique_ptr、mutex 等不可拷贝的可调用对象,满足 MoveConstructible/MoveAssignable 要求,不支持拷贝和 target 相关反射接口。

c++23 std::move_only_function怎么用 c++只能移动的函数包装器【详解】

std::move_only_function 是 C++23 引入的新特性,用来替代传统 std::function 中“仅支持可复制”这一限制,专为**只可移动(move-only)的可调用对象**设计。它不强制要求底层可调用对象支持拷贝,因此能包装 lambda 捕获了 unique_ptr、fstream、mutex 或其他不可拷贝资源的闭包,也能包装 std::unique_ptr<:any_callable> 等 move-only 类型。

为什么需要 move_only_function?

std::function 要求其模板参数 F 必须满足 CopyConstructible。这意味着:如果你写了一个捕获了 std::unique_ptr 的 lambda,它本身不可拷贝,就无法存入 std::function —— 编译直接失败。

std::move_only_function 只要求 MoveConstructibleMoveAssignable,彻底解除了拷贝约束,让 move-only 逻辑可以自然封装和传递。

基本用法与声明方式

它的模板形参和调用签名声明方式与 std::function 高度一致:

立即学习C++免费学习笔记(深入)”;

Z Code
Z Code

智谱AI推出的轻量级AI代码编辑器

下载
  • 声明格式:std::move_only_function,例如 std::move_only_function
  • 可由任何满足调用签名且可移动的可调用对象构造:lambda(含 move-only 捕获)、函数指针、move-only functor、std::unique_ptr
  • 不提供 .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
}

再比如包装一个临时的 std::unique_ptr<:function>> 或自定义 move-only 函数对象,也都适用。

注意事项与限制

  • 不能隐式转换为函数指针(即使目标是普通函数),因为 move-only 语义与函数指针的无状态本质冲突
  • 空状态检查仍用 if (f),但调用前务必判空(和 std::function 一致)
  • 性能上:内部通常依赖堆分配(类似 std::function),但实现可优化(如 small-buffer 优化对 move-only 类型更友好)
  • 不兼容旧标准:C++20 及更早无此类型;需编译器支持(GCC 13+、Clang 16+、MSVC 19.35+)并启用 -std=c++23

它不是 std::function 的“升级版”,而是互补角色:需要拷贝时用 std::function,只需移动时用 move_only_function —— 更精准表达意图,也更安全。

相关专题

更多
if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

709

2023.08.22

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

311

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

517

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

48

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

188

2025.08.29

javascriptvoid(o)怎么解决
javascriptvoid(o)怎么解决

javascriptvoid(o)的解决办法:1、检查语法错误;2、确保正确的执行环境;3、检查其他代码的冲突;4、使用事件委托;5、使用其他绑定方式;6、检查外部资源等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

172

2023.11.23

java中void的含义
java中void的含义

本专题整合了Java中void的相关内容,阅读专题下面的文章了解更多详细内容。

92

2025.11.27

lambda表达式
lambda表达式

Lambda表达式是一种匿名函数的简洁表示方式,它可以在需要函数作为参数的地方使用,并提供了一种更简洁、更灵活的编码方式,其语法为“lambda 参数列表: 表达式”,参数列表是函数的参数,可以包含一个或多个参数,用逗号分隔,表达式是函数的执行体,用于定义函数的具体操作。本专题为大家提供lambda表达式相关的文章、下载、课程内容,供大家免费下载体验。

202

2023.09.15

俄罗斯搜索引擎Yandex最新官方入口网址
俄罗斯搜索引擎Yandex最新官方入口网址

Yandex官方入口网址是https://yandex.com;用户可通过网页端直连或移动端浏览器直接访问,无需登录即可使用搜索、图片、新闻、地图等全部基础功能,并支持多语种检索与静态资源精准筛选。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1

2025.12.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号