”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > std::move() 如何处理 C++ 中的左值?

std::move() 如何处理 C++ 中的左值?

发布于2024-11-13
浏览:374

How Does std::move() Handle Lvalues in C  ?

std::move() 对左值有什么作用?

std::move() 是 C 语言中一个强大的工具,用于促进完美转发。然而,乍一看,它的实施可能会引起一些人的注意。为了阐明 std::move() 如何实现这一点,让我们深入研究其实现的复杂性。

理解“移动”函数

我们将从“move”函数模板的简化版本:

template 
typename remove_reference::type&& move(T&& arg)
{ return static_cast::type&&>(arg); }

情况 1:传递右值

当使用右值(临时对象或计算结果为右值的表达式)调用 std::move() 时,移动模板实例化如下:

// move with [T = Object]:
remove_reference::type&& move(Object&& arg)
{ return static_cast::type&&>(arg); }

由于remove_reference将Object转换为Object,我们最终得到:

Object&& move(Object&& arg) { return static_cast(arg); }

正如预期的那样,该函数只是将其右值参数转换为右值引用。

情况 2:传递左值

现在,有趣的是当使用左值(命名变量或计算结果的表达式)调用 std::move() 时,就会出现这种情况左值).

Object a; // a is lvalue
Object b = std::move(a);

这次,移动模板实例化为:

// move with [T = Object&]
remove_reference::type&& move(Object& && arg)
{ return static_cast::type&&>(arg); }

同样,remove_reference 将 Object& 转换为 Object,结果是:

Object&& move(Object& && arg) { return static_cast(arg); }

乍一看,这似乎违反直觉,因为我们传递了一个左值。然而,C 11引入了引用折叠的概念,它修改了引用语法的解释:

  • Object & & = Object &
  • Object & & && = 对象 &
  • 对象 & && & = 对象 &
  • 对象 & && & && = 对象 & &&

在这些规则下,Object& && 实际上表现为 Object&,一个可以绑定到左值的普通左值引用。

因此,函数的最终形式变为:

Object&& move(Object& arg) { return static_cast(arg); }

本质上,std::move() 将左值参数转换为右值引用,从而无论输入类型如何都能实现完美转发。

最新教程 更多>
  • 大批
    大批
    方法是可以在对象上调用的 fns 数组是对象,因此它们在 JS 中也有方法。 slice(begin):将数组的一部分提取到新数组中,而不改变原始数组。 let arr = ['a','b','c','d','e']; // Usecase: Extract till index p...
    编程 发布于2024-11-15
  • Bootstrap 4 Beta 中的列偏移发生了什么?
    Bootstrap 4 Beta 中的列偏移发生了什么?
    Bootstrap 4 Beta:列偏移的删除和恢复Bootstrap 4 在其 Beta 1 版本中引入了重大更改柱子偏移了。然而,随着 Beta 2 的后续发布,这些变化已经逆转。从 offset-md-* 到 ml-auto在 Bootstrap 4 Beta 1 中, offset-md-*...
    编程 发布于2024-11-15
  • 如何在 PHP 中组合两个关联数组,同时保留唯一 ID 并处理重复名称?
    如何在 PHP 中组合两个关联数组,同时保留唯一 ID 并处理重复名称?
    在 PHP 中组合关联数组在 PHP 中,将两个关联数组组合成一个数组是一项常见任务。考虑以下请求:问题描述:提供的代码定义了两个关联数组,$array1和$array2。目标是创建一个新数组 $array3,它合并两个数组中的所有键值对。 此外,提供的数组具有唯一的 ID,而名称可能重合。要求是构...
    编程 发布于2024-11-15
  • 除了“if”语句之外:还有什么地方可以在不进行强制转换的情况下使用具有显式“bool”转换的类型?
    除了“if”语句之外:还有什么地方可以在不进行强制转换的情况下使用具有显式“bool”转换的类型?
    无需强制转换即可上下文转换为 bool您的类定义了对 bool 的显式转换,使您能够在条件语句中直接使用其实例“t”。然而,这种显式转换提出了一个问题:“t”在哪里可以在不进行强制转换的情况下用作 bool?上下文转换场景C 标准指定了四种值可以根据上下文转换为 bool 的主要场景:语句:if、w...
    编程 发布于2024-11-15
  • 如何使用 MySQL 查找今天生日的用户?
    如何使用 MySQL 查找今天生日的用户?
    如何使用 MySQL 识别今天生日的用户使用 MySQL 确定今天是否是用户的生日涉及查找生日匹配的所有行今天的日期。这可以通过一个简单的 MySQL 查询来实现,该查询将存储为 UNIX 时间戳的生日与今天的日期进行比较。以下 SQL 查询将获取今天有生日的所有用户: FROM USERS ...
    编程 发布于2024-11-15
  • 如何修复 macOS 上 Django 中的“配置不正确:加载 MySQLdb 模块时出错”?
    如何修复 macOS 上 Django 中的“配置不正确:加载 MySQLdb 模块时出错”?
    MySQL配置不正确:相对路径的问题在Django中运行python manage.py runserver时,可能会遇到以下错误:ImproperlyConfigured: Error loading MySQLdb module: dlopen(/Library/Python/2.7/site-...
    编程 发布于2024-11-15
  • 在 Go 中使用 WebSocket 进行实时通信
    在 Go 中使用 WebSocket 进行实时通信
    构建需要实时更新的应用程序(例如聊天应用程序、实时通知或协作工具)需要一种比传统 HTTP 更快、更具交互性的通信方法。这就是 WebSockets 发挥作用的地方!今天,我们将探讨如何在 Go 中使用 WebSocket,以便您可以向应用程序添加实时功能。 在这篇文章中,我们将介绍: WebSoc...
    编程 发布于2024-11-15
  • **如何在不禁用索引的情况下优化 InnoDB 中的批量插入?**
    **如何在不禁用索引的情况下优化 InnoDB 中的批量插入?**
    禁用 InnoDB 中优化批量插入的索引在尝试禁用 InnoDB 表中的索引以增强批量插入性能时,您可能会遇到由于 InnoDB 存储引擎中缺少此功能而发出警告。以下是实现目标的替代策略:MySQL 参考建议:根据 MySQL 文档的建议,考虑使用以下命令:SET 自动提交=0;SET unique...
    编程 发布于2024-11-15
  • 如何使用命令式方法更新 React 中的嵌套状态?
    如何使用命令式方法更新 React 中的嵌套状态?
    更新嵌套状态的命令式方法在 React 中,状态更新是不可变的。这意味着要更新嵌套对象或数组,您不能简单地修改其属性并期望更改反映在 UI 中。相反,您需要创建一个包含更新值的新对象或数组,然后将其传递给 setState。考虑以下示例,其中我们要更新对象中索引 1 处的对象的 name 属性存储在...
    编程 发布于2024-11-14
  • 原子变量有哪些不同的内存排序模型?
    原子变量有哪些不同的内存排序模型?
    理解内存排序的含义原子变量提供安全的内存访问和跨线程同步。了解不同的内存顺序对于有效利用它们至关重要。轻松:无内存同步。可能重新排序的优化操作读取和写入。顺序一致 (seq_cst):最严格的排序。防止对周围的任何内存操作进行重新排序原子操作。确保所有线程的内存访问一致。获取/释放:宽松之间的混合和...
    编程 发布于2024-11-14
  • 为什么在 For 循环中放错 Return 语句会影响输入循环?
    为什么在 For 循环中放错 Return 语句会影响输入循环?
    For循环中返回语句错位在你的作业中,你遇到了一个问题,程序只允许输入一只宠物,尽管瞄准三个。这个问题源于 make_list 函数中 return 语句的定位。在 for 循环中,return 语句在到达函数时立即终止函数的执行。在提供的代码中,return 语句放置在循环内部,导致函数在第一次迭...
    编程 发布于2024-11-14
  • 如何防止用户关闭 Bootstrap 模式?
    如何防止用户关闭 Bootstrap 模式?
    禁用用户启动的 Bootstrap 模态退出您可以通过单击 Bootstrap 模态区域外部来阻止用户关闭 Bootstrap 模态。这在您想要强制用户在继续操作之前与特定模态内容交互的情况下非常有用。禁用模态背景点击关闭默认情况下,用户可以通过单击模式窗口之外的任意位置来关闭模式。要禁用此行为:在...
    编程 发布于2024-11-14
  • 如何在 Python 中将嵌套列表导出到 CSV 文件?
    如何在 Python 中将嵌套列表导出到 CSV 文件?
    在Python中将嵌套列表导出到CSV文件将嵌套列表(其中每个内部列表包含不同类型的元素)写入CSV文件可以在 Python 中处理数据时这是一项常见任务。以下是应对这一挑战的方法:Python 的 csv 模块提供了处理 CSV 操作的便捷方法。要将列表的列表(例如 a = [[1.2,'...
    编程 发布于2024-11-14
  • 如何高效提取Go Slice的最后一个元素?
    如何高效提取Go Slice的最后一个元素?
    Go 提取切片最后一个元素的最佳方法在 Go 中使用切片时,有效操作元素至关重要。一个常见的任务是提取最后一个元素,这可以通过多种方法来实现。现有解决方案的缺点使用切片提供的解决方案[len(slice)-1 :][0] 看起来很麻烦并且涉及不必要的复杂性。它返回一个仅包含最后一个元素的切片,然后使...
    编程 发布于2024-11-14
  • 为什么我的 JavaScript 事件在动态元素追加后没有触发?
    为什么我的 JavaScript 事件在动态元素追加后没有触发?
    动态元素追加后 JavaScript 事件未触发您遇到了向 DOM 追加新元素后 JavaScript 事件未触发的问题。这是因为 jQuery 仅识别页面加载期间最初运行时存在的元素。要解决此问题,您需要使用事件委托来捕获动态元素中的事件。事件委托涉及捕获页面加载期间已经存在的 DOM 中更高级别...
    编程 发布于2024-11-14

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3