第五章
-
第一次学习时,移动语义和完美转发的意思看起来很直白:
- 移动语义使编译器能把昂贵的拷贝操作换为移动操作。类似于拷贝构造/赋值函数,你可以通过移动构造/赋值函数来控制移动的语义。移动语义还允许你创建仅移动(不能复制)的类型,如
std::unique_ptr
,std::future
和std::thread
。 - 完美转发允许函数模板接受任意(左值/右值)参数,并将它们原样传递给其它的函数。
- 移动语义使编译器能把昂贵的拷贝操作换为移动操作。类似于拷贝构造/赋值函数,你可以通过移动构造/赋值函数来控制移动的语义。移动语义还允许你创建仅移动(不能复制)的类型,如
-
右值引用是使以上二者可能实现的低层语言机制
-
然而随着对这些特性的掌握变深,你会发现最初的印象只是冰山一角。移动语义,完美转发和右值引用远比其表面更微妙。例如,
std::move
不会移动任何东西,完美转发也并不完美。移动并不一定比拷贝开销低,也不一定在可以被移动时总被调用。type&&
并不总代表右值引用。 -
本章就将带你深入至这一切的根基。你会了解
std::move
和std::forward
的使用方法,习惯type&&
模糊的本性,理解移动操作性能惊人差异的原因。当一切云开雾散,你会回到一切的起点,移动语义,完美转发和右值引用再次显得无比自然。
以下为各条款(Item)链接:
Item 23: 理解 std::move
和 std::forward
Item 24: 区分万能引用和右值引用
Item 25: 对右值引用参数使用std::move,对万能引用参数使用std::forward
Item 26: 避免对万能引用参数进行重载
Item 27: 了解对万能引用进行重载的替代方案
Item 28: 理解引用折叠(reference collapsing)
Item 29: 移动操作的“坑点”:它们可能不存在,开销不小或不会被调用
Item 30: 了解完美转发失效的场景