[h1]背景[/h1]最近同学想到一个问题,有关C++的右值引用。我本以为自己读了两遍C++ Primer,总该得心应手,却发现越解释,越迷糊。
这篇文章不会介绍有关右值引用和移动构造函数的概念,而是直接通过描述同学的问题并深入探讨,来尝试解释一些右值引用、移动构造和完美转发的具体用途。
[h1]问题[/h1]STL里面的std::map::insert,有两个方法的重载:
- 自C++11
- template std::pair insert(P&& value);
复制代码 - 自C++17
- std::pair insert(value_type&& value);
复制代码 这两个方法有什么不同用途?为什么在C++17时,又增加了第二个方法重载?
[h1]一些知识点[/h1]- 只是一个到右值的类型转换,并不做任何其他实质性的事情。
- 右值引用的右值引用可以合成为右值引用,其他的引用组合都只能合称为左值引用:
- typedef int& lref;typedef int&& rref;int n;lref& r1 = n; // type of r1 is int&lref&& r2 = n; // type of r2 is int&rref& r3 = n; // type of r3 is int&rref&& r4 = 1; // type of r4 is int&&
复制代码 - 右值引用变量在表达式中是左值:
- int&& x = 1;f(x); // calls f(int& x)f(std::move(x)); // calls f(int&& x)
复制代码 - 转发引用是一种特殊的引用,可以保留函数参数的原始类别。
比如,模板函数参数声明为没有const/volatile修饰符的右值引用类型:- templateint f(T&& x) { // x is a forwarding reference return g(std::forward(x)); // and so can be forwarded}int main() { int i; f(i); // argument is lvalue, calls f(int&), std::forward(x) is lvalue f(0); // argument is rvalue, calls f(int&&), std::forward(x) is rvalue}
复制代码 [h1]实验 1[/h1]想搞清楚那两个方法的用途,最好的办法就是用一下他们。
不过方法过于复杂,我们写一个简单的程序,有类似的方法:[code]#include #include #include using namespace std;struct A{ string str; A(const A& a) : str(a.str) { cout |
|