c++11新的移动语义确实可以减少了不必要的对象拷贝工作,但是由此引发的左值右值语法却着实令人讨厌,尤其是在模板推导时的引用折叠操作真的是服气,关于引用折叠及完美转发《深入理解c++11》和《深入应用c++11》这两本书都有做介绍。
看了几篇大佬博客,有所收获却头皮发麻,记录如下:
1.https://blog.csdn.net/linuxheik/article/details/69536909?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.control
2.https://blog.csdn.net/WizardtoH/article/details/80718605?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.control
3.https://blog.csdn.net/guangcheng0312q/article/details/103572987?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control
4.https://www.douzhq.cn/c11_5/
总结:
1.c++11后类中多了两种构造函数(移动构造A(A&& tmp)和移动赋值operator(A&& tmp) ),临时类A不能是const的,因为要将其里边所带的指针移动到this后置空,这个没啥好说就是提升了效率,减少临时对象的构造和析构消耗
其伪码如下
A(A&& tmp):ptr(tmp.ptr)//初始化列表里将A类的成员ptr进行复制操作,使this->ptr和tmp.ptr指向一样,相当于浅拷贝 { tmp.ptr=nullptr; //置空,不然就和浅拷贝一样两个指针指向同一块内存,两个指针析构两次必出问题 }
2.在函数模板中做类型传递的时候,由于模板类型推导而形成的诡异操作
例如下边的函数模板,f的参数T&&,第一眼我们肯定觉得他是右值引用,但是其实不然,T&&当传入的实参是左者引用是会被折叠为T&,当为右值引用时才是我们理解的T&&,
tempalte<typename T> void f(T&&);
《effective modern c++》第一讲就是关于模板类型推导
3.引用折叠
其实就是模板参数传入的是左值引用还是右值引用的使其产生不同的推导参数,与上一点讲的是同一件事。
4.完全转发
下边这个大佬写了个小例子可以说明完全转发的作用
https://www.douzhq.cn/c11_5/
示例代码如下:
#include <iostream> #include <stdlib.h> #include <type_traits> void func(int& t) { std::cout << "func(int& t)" << std::endl; } void func(const int& t) { std::cout << "func(const int& t)" << std::endl; } void func(const int&& t) { std::cout << "func(const int&& t)" << std::endl; } template<typename T> void perfectForward(T&& t) { func(std::forward<T>(t)); //完全转发 //func(t); } int main(int argc, char** argv) { int a = 0; perfectForward(a); const int b = 20; perfectForward(b); perfectForward(std::move(a)); system("pause"); return 0; }
输出结果:
ps:关于右值在新标准中的具体使用大概只能从标准库里看看实现了,写了这么多还是云里雾里,只希望大伙不要被我误导哈哈,有时间去找找,单看这些概念并没有什么大用处。