C++ Primer 5th笔记(chap 16 模板和泛型编程)std::move

Posted thefist11

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++ Primer 5th笔记(chap 16 模板和泛型编程)std::move相关的知识,希望对你有一定的参考价值。

1. 标准库定义

/ / 在返回类型和类型转换中也要用到 typename, 参见 16.1.3 节( 第 593 页 )
reference 是在 16.2.3 节( 第 605 页 ) 中介绍的
template typename remove reference::type&& move (T && t )
{
// static_cast 是在 4.11.3 节( 第 145 页 ) 中介绍的
return static_cast<typename remove reference::type&&> (t);
}

move 的函数参数 T &&是一个指向模板类型参数的右值引用。 通过引用折叠, 此参数可以与任何类型的实参匹配。 特别是, 我们既可传递给 move—个左值, 也可以传递给它一个右值
string si (“hi!”), s2;
s2=std::move (string (“bye!” ) ); // 正确: 从一个右值移动数据
s2=std::move(si); // 正确: 但在赋值之后 , si 的值是不确定的

1.1 s2=std::move (string (“bye!” ) );

  • 推断出 T 的类型为 string。
  • remove_reference 用 string 进行实例化。
  • reference type 成员是 string。
  • move返回类型是 string&&。
  • move的函数参数 t 的类型为 string& &。

因此, 这个调用实例化 move, 即函数string && move (string &&t )

1.2 s2=std::move(si);

  • 推断出T的类型为 string& (string 的引用, 而非普通 string)。
  • remove—reference 用 string&进行实例化。
  • remove_reference<string&>的 type 成员是 string。
  • move的返冋类型仍是 string& &。
  • move的函数参数 t 实例化为 string& & & , 会折叠为 string&。

因此, 这个调用实例化 move<string&>, 即string && move (string &t )

从一个左值 static_cast 到一个右值引用是允许的

  • 通常情况下, static_cast 只能用于其他合法的类型转换( 参见 4.11.3 节, 第 145页)。 但是, 这里又有一条 对右值引用的特许规则: 虽然不能隐式地将一个左值转换为右值引用, 但我们可以用 static_cast 显式地将一个左值转换为一个右值引用。

  • 对于操作右值引用的代码来说, 将一个右值引用绑定到一个左值的特性允许它们截断左值。 有时候, 例如在我们的 StrVec 类的 reallocate 函数( 参见 13.6.1 节, 第 469页) 中, 我们知道截断一个左值是安全的。 一方面, 通过允许进行这样的转换, C++语言认可了这种用法。 但另一方面, 通过强制使用 static_cast, C++语言试图阻止我们意外地进行这种转换。

最后, 虽然我们可以直接编写这种类型转换代码, 但使用标准库 move 函数是容易得多的方式。 而且, 统一使用 std::move 使得我们在程序中查找潜在的截断左值的代码变得很容易

以上是关于C++ Primer 5th笔记(chap 16 模板和泛型编程)std::move的主要内容,如果未能解决你的问题,请参考以下文章

C++ Primer 5th笔记(chap 16 模板和泛型编程)std::move

C++ Primer 5th笔记(chap 16 模板和泛型编程)模板特例化

C++ Primer 5th笔记(chap 16 模板和泛型编程)类模板特例化

C++ Primer 5th笔记(chap 16 模板和泛型编程)实例化

C++ Primer 5th笔记(chap 16 模板和泛型编程)可变参数模板

C++ Primer 5th笔记(chap 16 模板和泛型编程)模板实参