当前位置: 首页 > news >正文

Modern C++ std::move的实现原理

前言

有一节我们分析了std::bind的实现原理,本节稍作休息分析一个比较简单的std::move

原理

std::move的原理太简单了,一句话:就是把传进来的参数强转为右值引用类型。作用为调用移动构造函数,或移动赋值函数。下面通过例子和代码说明。

例子

#include <iostream>
#include <cstring>using namespace std;struct Thing {Thing(){cout << "default construct\n";}// Copy operatorThing(const Thing& other){cout << "copy constructor\n";}// Move constructorThing(Thing&& other) noexcept{cout << "move constructor\n";}// assignment operatorThing& operator=(const Thing& rhs) {cout << "copy operator\n";return *this;}// move assignment operatorThing& operator=(Thing&& rhs) noexcept {cout << "move operator\n";return *this;}// destructor necessary since we are working in dangerous new/delete territory~Thing() noexcept {cout << "destructor " << "\n";}
};
int main()
{cout << "main::constructing a\n";Thing a;cout << "main::moving a to newly constructed c\n";Thing c(std::move(a));Thing x = std::move(c);cout << ">main::thing y\n";Thing y;y = std::move(x);return 0;
}

[mzhai@c++11]$ ./a.out
main::constructing a
default construct
main::moving a to newly constructed c
move constructor //Thing c(std::move(a));
move constructor //Thing x = std::move©;
main::thing y
default construct
move operator //y = std::move(x);
destructor
destructor
destructor
destructor

a, c, x虽然都是左值,但std::move却把它们强转成了右值引用,从而调用了move语义的函数而不是copy语义的。

std::move源码

 92   /**93    *  @brief  Convert a value to an rvalue.94    *  @param  __t  A thing of arbitrary type.95    *  @return The parameter cast to an rvalue-reference to allow moving it.96   */97   template<typename _Tp>98     constexpr typename std::remove_reference<_Tp>::type&&99     move(_Tp&& __t) noexcept
100     { return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); }

让我们看看remove_reference 的定义,看看它是怎么脱去类型的外衣的:

1402   /// remove_reference
1403   template<typename _Tp>
1404     struct remove_reference
1405     { typedef _Tp   type; };
1406
1407   template<typename _Tp>
1408     struct remove_reference<_Tp&>
1409     { typedef _Tp   type; };
1410
1411   template<typename _Tp>
1412     struct remove_reference<_Tp&&>
1413     { typedef _Tp   type; };

原来不管你原来的类型是左值引用还是右值引用,统统都定义type为脱去外衣的类型。

相关文章:

Modern C++ std::move的实现原理

前言 有一节我们分析了std::bind的实现原理&#xff0c;本节稍作休息分析一个比较简单的std::move 原理 std::move的原理太简单了&#xff0c;一句话&#xff1a;就是把传进来的参数强转为右值引用类型。作用为调用移动构造函数&#xff0c;或移动赋值函数。下面通过例子和代…...

爬虫工作量由小到大的思维转变---<第四十章 Scrapy Redis 实现IP代理池管理的最佳实践>

前言: 本篇是要结合上篇一起看的姊妹篇:爬虫工作量由小到大的思维转变---&#xff1c;第三十九章 Scrapy-redis 常用的那个RetryMiddleware&#xff1e;-CSDN博客 IP代理池的管理对于确保爬虫的稳定性和数据抓取的匿名性至关重要。围绕Scrapy-Redis框架和一个具体的IP代理池中…...

C# 实现 XOR 密码

XOR密码&#xff08;异或密码&#xff09;是一种简单的加密算法&#xff0c;它使用异或&#xff08;XOR&#xff09;操作来对明文和密钥进行加密和解密。 异或操作是一种位运算&#xff0c;它对两个二进制数的对应位进行比较&#xff0c;如果两个位相同&#xff08;都为0或都为…...

【Web前端开发基础】CSS3之空间转换和动画

CSS3之空间转换和动画 目录 CSS3之空间转换和动画一、空间转换1.1 概述1.2 3D转换常用的属性1.3 3D转换&#xff1a;translate3d&#xff08;位移&#xff09;1.4 3D转换&#xff1a;perspective&#xff08;视角&#xff09;1.5 3D转换&#xff1a;rotate3d&#xff08;旋转&a…...

Go实现一个简单的烟花秀效果(附带源码)

在 Go 语言中&#xff0c;要实现烟花秀效果可以使用 github.com/fogleman/gg 包进行绘图。以下是一个简单的例子&#xff1a; 首先&#xff0c;确保你已经安装了&#xff08;有时候需要梯子才可以安装&#xff09; github.com/fogleman/gg 包&#xff1a; go get -u github.c…...

【数学建模】插值与拟合

文章目录 插值插值方法用Python解决插值问题 拟合最小二乘拟合数据拟合的Python实现 适用情况 处理由试验、测量得到的大量数据或一些过于复杂而不便于计算的函数表达式时&#xff0c;构造一个简单函数作为要考察数据或复杂函数的近似 定义 给定一组数据&#xff0c;需要确定满…...

全卷积网络:革新图像分析

一、介绍 全卷积网络&#xff08;FCN&#xff09;的出现标志着计算机视觉领域的一个重要里程碑&#xff0c;特别是在涉及图像分析的任务中。本文深入探讨了 FCN 的概念、它们的架构、它们与传统卷积神经网络 &#xff08;CNN&#xff09; 的区别以及它们在各个领域的应用。 就像…...

ubuntu20.04 格式化 硬盘 扩展硬盘GParted

如何在 Ubuntu 22.04 LTS 上安装分区编辑器 GParted&#xff1f;_gparted安装-CSDN博客 sudo apt install gparted 步骤5&#xff1a;启动GParted 安装完成后&#xff0c;您可以在应用程序菜单中找到GParted。点击它以启动分区编辑器。 通过以上步骤&#xff0c;您可以在Ubun…...

docker的资源限制(cgroup)

前瞻 Docker 通过 Cgroup 来控制容器使用的资源配额&#xff0c;包括 CPU、内存、磁盘三大方面&#xff0c; 基本覆盖了常见的资源配额和使用量控制。 Cgroup 是 ControlGroups 的缩写&#xff0c;是 Linux 内核提供的一种可以限制、记录、隔离进程组所使用的物理资源(如 CPU、…...

ChatGPT与文心一言:应用示例与体验比较

ChatGPT 和文心一言哪个更好用&#xff1f; 为了更好地感受ChatGPT和文心一言这两款AI助手如何在实际运用中竞相辉映&#xff0c;我将提供一些典型的应用示例。这些示例都取自真实的用户体验&#xff0c;以帮助解释这两种工具如何让日常生活或工作变得更加轻松。 ChatGPT Ch…...

紫光展锐T760_芯片性能介绍_展锐T760安卓核心板定制

展锐T760核心板是一款基于国产5G芯片的智能模块&#xff0c;采用紫光展锐T760制程工艺为台积电6nm工艺&#xff0c;支持工艺具有出色的能效表现。其采用主流的44架构的八核设计&#xff0c;包括4颗2.2GHz A76核心和4颗A55核心设计&#xff0c;内存单元板载可达8GB Ram256GB ROM…...

从动力系统研究看当今数学界

6.3... Milnor’s definition of “attractors” which has been criticized above by us). The work of [KSS2] of asserting the existence of “nice open set” of Ω(p.148) would be likely not verified, for example we think the first sentence “… since f is nont…...

【征服redis15】分布式锁的功能与整体设计方案

目录 1. 分布式锁的概念 2.基于数据库做分布式锁 2.1 基于表主键唯一做分布式锁 2.2 基于表字段版本号做分布式锁 2.3 基于数据库排他锁做分布式锁 3.使用Redis做分布式锁 3.1 redis实现分布式锁的基本原理 3.2 问题一&#xff1a;增加超时机制&#xff0c;防止长期持有…...

MATLAB中实现机械臂逆运动学求解的方法之一是使用阻尼最小二乘法

MATLAB中实现机械臂逆运动学求解的方法之一是使用阻尼最小二乘法。阻尼最小二乘法通常用于处理数值求解问题中的不稳定性和噪声。以下是一个简单的MATLAB代码示例&#xff0c;演示了机械臂逆运动学的阻尼最小二乘法求解&#xff1a; % 机械臂参数 L1 1; % 机械臂长度 L2 1;…...

2024.1.24 GNSS 学习笔记

1.伪距观测值公式 2.载波相位观测值公式 3.单点定位技术(Single Point Positionin, SPP) 仅使用伪距观测值&#xff0c;不使用其他的辅助信息获得ECEF框架下绝对定位技术。 使用广播星历的轨钟进行定位&#xff0c;考虑到轨钟的米级精度&#xff0c;所以对于<1米的误差&…...

2024-01-22(MongoDB)

1.Mongodb使用的业务场景&#xff1a; 传统的关系型数据库/mysql在“三高”需求以及应对web2.0的网站需求面前&#xff0c;有点力不从心&#xff0c;什么是“三高”需求&#xff1a; a. 对数据库高并发的读写需求 b. 对海量数据的高效率存储和访问需求 c. 对数据库的高可扩…...

无人机航迹规划(六):七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划(提供MATLAB代码)

一、七种算法&#xff08;DBO、LO、SWO、COA、LSO、KOA、GRO&#xff09;简介 1、蜣螂优化算法DBO 蜣螂优化算法&#xff08;Dung beetle optimizer&#xff0c;DBO&#xff09;由Jiankai Xue和Bo Shen于2022年提出&#xff0c;该算法主要受蜣螂的滚球、跳舞、觅食、偷窃和繁…...

《WebKit 技术内幕》学习之十二(2):安全机制

2 沙箱模型 2.1 原理 一般而言&#xff0c;对于网络上的网页中的JavaScript代码和插件是不受信的&#xff08;除非是经过认证的网站&#xff09;&#xff0c;特别是一些故意设计侵入浏览器运行的主机代码更是非常危险&#xff0c;通过一些手段或者浏览器中的漏洞&#xff0c…...

算法优化:LeetCode第122场双周赛解题策略与技巧

接下来会以刷常规题为主 &#xff0c;周赛的难题想要独立做出来还是有一定难度的&#xff0c;需要消耗大量时间 比赛地址 3011. 判断一个数组是否可以变为有序 public class Solution {public int minimumCost(int[] nums) {if (nums.length < 3) {// 数组长度小于3时&a…...

IDEA导出jar

1、选择导出方式 2、选择Main Class 3、构建jar...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

MFC 抛体运动模拟:常见问题解决与界面美化

在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...

android13 app的触摸问题定位分析流程

一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...

手机平板能效生态设计指令EU 2023/1670标准解读

手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读&#xff0c;综合法规核心要求、最新修正及企业合规要点&#xff1a; 一、法规背景与目标 生效与强制时间 发布于2023年8月31日&#xff08;OJ公报&…...

springboot 日志类切面,接口成功记录日志,失败不记录

springboot 日志类切面&#xff0c;接口成功记录日志&#xff0c;失败不记录 自定义一个注解方法 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/***…...