Administrator
发布于 2025-08-29 / 3 阅读
0
0

移动语义(Move Semantics)和完美转发(Perfect Forwarding)

    移动语义(Move Semantics)和完美转发(Perfect Forwarding)是 C++11 引入的核心特性,旨在提升程序性能并解决泛型编程中的参数传递问题。

### 移动语义

    在了解移动意义之前,需要先掌握两个概念:**右值(Rvalue)**和**右值引用(Rvalue Reference)**:

- 右值(Rvalue):临时对象(如函数返回值)、字面量(如 42)、显式标记为右值的对象(std::move(x))。

- 右值引用(Rvalue Reference):用 &&声明的引用(如 T&&),只能绑定到右值。

    C++类默认成员函数中的**移动构造函数**/**移动赋值运算符**便是右值引用的应用。

    再来说说**移动语义(Move Semantics)**引入的目的是解决深拷贝带来的性能开销,通过“转移资源所有权”而非复制资源来优化临时对象的处理。

    C++提供了 std::move ,将资源从临时对象“窃取”到新对象,提升性能:

Vector v1(1000); // 构造 v1

Vector v2 = std::move(v1); // 调用移动构造函数,v1 的资源被转移到 v2

//此后 v1 处于有效但未定义状态(通常为空)。

### 完美转发

    针对泛型编程中丢失原始类别问题:

template <typename T>

void wrapper(T arg) {

func(arg); // 丢失了 arg 的原始类别(总是视为左值)

}

&ensp;&ensp;&ensp;&ensp;万能引用(Universal Reference)+ 完美转发(Perfect Forwarding)提供了一种在泛型代码中**保持参数的原始类型**(左值/右值)和常量性,确保参数被正确传递的方案-**std::forward**

- 万能引用(Universal Reference)

template <typename T>

void wrapper(T&& arg) { // 万能引用(T&&) 可绑定到左值/右值

func(???); // 如何保持 arg 的原始类别?

}

- 引用折叠规则如下:

T& & (左值引用的左值引用) 折叠为 T&

T& && (左值引用的右值引用) 折叠为 T&

T&& & (右值引用的左值引用) 折叠为 T&

T&& && (右值引用的右值引用) 折叠为 T&&

//只要出现一个 &,结果就是左值引用(左值引用具有传染性)

//仅当两个都是 && 时,结果才是右值引用

- std::forward:

template <typename T>

void wrapper(T&& arg) {

func(std::forward<T>(arg)); // 保持 arg 的原始类型

}

//若 arg 是左值,std::forward 返回左值引用。

//若 arg 是右值,std::forward 返回右值引用。


评论