move

关键的话:

std::move 并不进行任何移动,std::forward 也不进行任何转发。

move 和 forward 在运行期都无所作为。不会生成任何可执行代码,连一个字节都不会生成。

函数形参永远是左值。 具名变量永远是左值。但是不具名的变量不一定是右值。(例如字符串字面量 “hello world” 也是左值)

参考:
https://zh.cppreference.com/w/cpp/language/identifiers

命名某个变量、函数、概念的特化 (C++20 起)或枚举项的标识符可以作为表达式使用。仅由这个标识符组成的表达式的结果,是该标识符所命名的实体。若该标识符命名的是某个函数、变量、模板形参对象 (C++20 起)或数据成员,则表达式的值类别为左值,否则为纯右值(例如枚举项是纯右值表达式,概念的特化是 bool 纯右值 (C++20 起))。

可以看到,一个枚举项命名的并非是某个函数、变量、模板形参对象 (C++20 起)或数据成员,因此非左值,为纯右值。

我理解中左值就是可以出现在operator=左侧,而右值是只能出现在operator=右侧。
但是对于C++自定义的类,会有一些意外。比如string()是一个临时对象但也能放在左边,不过没有意义。

值类别参考:https://zh.cppreference.com/w/cpp/language/value_category

再参考标准规格书:ISO_IEC_14882__2020-12

In general, the effect of this rule is that named rvalue references are treated as lvalues and unnamed rvalue references to objects are treated as xvalues; rvalue references to functions are treated as lvalues whether named or not.

具名右值引用是一个左值,不具名右值引用是一个亡值 (xvalue)(“将亡 (expiring)”的值)

forward

forward 不进行任何转发。只是在某个特定条件满足下执行一个强制转换(static_cast)罢了。

首先理解万能引用的模板推导规则:

template<typename T>
void f(T&& param);

万能引用只能是 T&& 的形式,即 T 不能被修饰(如 cv 修饰符,否则为右值引用形式)。

推导规则:左值 则 T 被推导为 左值引用,右值 则 T 被推导为 不带引用的情况。

例如(一个简单的测试万能引用的程序):

#include <iostream>
#include <type_traits>template<typename T>
void f(T&& param)
{std::cout << std::boolalpha;std::cout << std::is_reference_v<T> << std::endl;//std::cout << std::is_reference_v<decltype(param)> << std::endl;
}int main()
{const int a = 5;f(a); // T 为 const int& f(10);
}

推导不会丢掉 cv 修饰符 (cv (const and volatile) type qualifiers)。

boolalpha操纵符,否则 ture 会输出为 1

引用折叠:&& + && == &&

只有四种语境会发生:模板实例化、auto型别生成、创建和运用 typedef 和别名声明、decltype

个人观点:其实就是推导(deduction)语境。

简单示例:

#include <vector>std::vector<int> vec;template<typename T>
void f(T&& param)
{vec.push_back(std::forward<T>(param));
}int main()
{int b = 5;const int& a = b;f(5);f(a);
}

关于 _t 与 _v

参考:https://rules.sonarsource.com/cpp/RSPEC-6020

The “_t” and “_v” version of type traits should be used instead of “::type” and “::value”

Even if the old variant still exists, the new one, which uses _t (C++14) and _v (C++17) suffixes as discriminant, should be preferred.

template<class T>
void f(T t) {static_assert (std::is_arithmetic<T>::value); // Noncompliantusing rawType = std::remove_cv<T>::type; // Noncompliant
}
template<class T>
void f(T t) {static_assert (std::is_arithmetic_v<T>); // Compliant, C++17using rawType = std::remove_cv_t<T>; // Compliant, C++14
}

top-level const qualifier

C++Primer 5th 2.4.3 :

可见,常量指针为顶层const,指向常量的指针为底层const,const int* const 既是顶层又是底层。引用则没有顶层。

is_const_v 只能检查顶层const。要检查底层const,如下:

std::cout << std::boolalpha;
std::cout << std::is_const_v<const int> << std::endl;
std::cout << std::is_const_v<std::remove_pointer_t<const int*>> << std::endl;
std::cout << std::is_const_v<std::remove_reference_t<const int&>> << std::endl;

输出全为 true。

move 和 forward相关推荐

  1. C++ std::move/std::forward/完美转发

    右值引用相关的几个函数:std::move, std::forward 和 成员的 emplace_back; 通过这些函数我们可以避免不必要的拷贝,提高程序性能. move 是将 对象的状态 或者 ...

  2. C++语法——右值引用、移动构造和赋值、万能引用和转发、move和forward底层实现

    目录 一.右值引用 (一).何为右值 (二).右值引用 (三).右值和左值的互相传递 ①左值->右值引用 ②右值->左值引用 (四).右值引用的自身属性 二.移动构造和移动赋值 (一).移 ...

  3. 深入理解C++中的move和forward!

    导语 |  在C++11标准之前,C++中默认的传值类型均为Copy语义,即:不论是指针类型还是值类型,都将会在进行函数调用时被完整的复制一份!对于非指针而言,开销极其巨大!因此在C++11以后,引入 ...

  4. c++11 中的 move 与 forward

    一. move 关于 lvaue 和 rvalue,在 c++11 以前存在一个有趣的现象:T&  指向 lvalue (左传引用), const T& 既可以指向 lvalue 也可 ...

  5. c++11特性move和forward区别

    1:move属于强转,左值变右值 2:forward左值变左值,右值变右值(不是强转)

  6. (原创)C++11改进我们的程序之move和完美转发

    http://www.cnblogs.com/qicosmos/p/3376241.html 本次要讲的是右值引用相关的几个函数:std::move, std::forward和成员的emplace_ ...

  7. 一文详解点云分割算法

    作者丨书生意封侯@知乎 来源丨https://zhuanlan.zhihu.com/p/470782623 编辑丨3D视觉工坊 从某种意义上说,地面点剔除(分割)也属于点云分割的一种,但两者技术路线有 ...

  8. 程序员的量化交易之路(35)--Lean之DataFeed数据槽3

    转载需注明出处:http://blog.csdn.net/minimicall,http://cloudtrade.top/ Lean引擎的模块划分非常的规范.其中DataFeed是数据槽,就是供应数 ...

  9. 全部python编程语言-可以用 Python 编程语言做哪些神奇好玩的事情?

    贪吃蛇.迷宫.吃豆人.扫雷.Flappy Bird...这些游戏可以是非常经典,甚至伴随着很多人的童年回忆.那么,你是否想过自己开发一款专属游戏?是否思考过开发这样一款游戏需要多少工作量? /> ...

最新文章

  1. 「镁客早报」阿里巴巴与Office Depot合作,服务美国小企业;HTC与印厂商谈品牌许可协议,或退出手机市场...
  2. commonjs是什么_第一步:面试官让我解释什么是Common.js和ES6模块化
  3. Java JDBC
  4. 牛客网——10进制 VS 2进制
  5. android.animation(1) - ValueAnimator的ofInt(), ofFloat(), addUpdateListener(), addListener()(转)
  6. lowerBound与upperBound
  7. perl6正则 4: before / after 代码断言: ?{} / !{}
  8. 内置对象和自定义对象的原型链
  9. 软件版本控制Subversion和Git
  10. wsdl2java wsdl文件_使用axis2的wsdl2java把wsdl生成java文件
  11. 来料加工企业使用ERP系统作用有哪些
  12. 二阶魔方万能还原公式_【二阶篇】一个万能公式还原二阶魔方
  13. web前端vue项目完整步骤。pc端
  14. 实现Excel单元格中的下拉选项和数据有效性
  15. 微信小程序可以打开公众号文章
  16. 闪购网站Gilt从Rails迁移到Scala
  17. 炼数成金数据分析课程---13、回归分析
  18. 数字化招聘:猎聘、快手同行不同路
  19. so动态库生成、链接方法
  20. 数图互通高校房产管理——公积金补贴管理

热门文章

  1. ROOK-03 rook ceph集群使用和管理
  2. TIME_WAIT状态、危害、如何避免危害
  3. 跟踪sys_mkdir的系统调用过程
  4. 山东大学软件学院高级语言课程设计JAVA课程设计-学生在线考试系统平台
  5. 上帝保佑!!!哈利路亚!!!阿门!!!
  6. 通用文件模型及VFS-VFS结构
  7. JS的字符串操作和各种格式转换
  8. 今日科技联播:10年后中国研发实力将超越日本?
  9. 一种叶片叶绿素含量(Leaf chlorophyll content, LCC)测定方法
  10. 必学Java类库/常用Java类库大全(awesome-java)