C++ 引用魔法揭秘:std::move 和 std::forward 的真相

之前我们聊过左值右值的基础概念,今天我们来讲讲C++里的两个神秘工具函数 —— std::movestd::forward🧙‍♂️

对左值与右值右疑惑的小伙伴看这里~:
C++左值、右值你分清了吗
深入理解 C++ 中的引用:左值引用与右值引用

🧭 std::move:不是移动,而是“允许移动”

移动语义的目的是通过窃取资源(而不是拷贝)来提高性能,这在处理大对象时尤其有用。

但是很多人看到 std::move(obj),下意识以为这就把 obj 的内容“搬走”了,但实际上:

std::move 不移动任何东西。它只是一个类型转换工具,把一个左值变成一个右值,从而允许调用移动构造或移动赋值函数。

🌟 示例:触发移动构造

#include <iostream>
#include <vector>

class TestClass {
public:
    std::vector<int> data;

    TestClass() {
        data.push_back(1);
        data.push_back(2);
        data.push_back(3);
        std::cout << "默认构造\n";
        std::cout << "This  vector size : " << data.size() << std::endl;
    }

    TestClass(const TestClass& other) {
        std::cout << "拷贝构造\n";
    }

    TestClass(TestClass&& other) noexcept {
        std::cout << "移动构造\n";
        std::cout << "Other vector size brefore move: " << other.data.size() << std::endl;
        std::cout << "This  vector size brefore move: " << data.size() << std::endl;
        data = std::move(other.data);  // 此处窃取资源
        std::cout << "Other vector size after move: " << other.data.size() << std::endl;
        std::cout << "This  vector size after move: " << data.size() << std::endl;
    }
};

int main() {
    TestClass a;
    std::cout << "----------------------\n";
    TestClass b = std::move(a);  // a 是左值,但 std::move(a) 是右值,从而触发移动构造
}

执行结果:

默认构造
This  vector size : 3
----------------------
移动构造
Other vector size brefore move: 3
This  vector size brefore move: 0
Other vector size after move: 0
This  vector size after move: 3

🌀 std::forward:完美地保留值类别

在泛型编程中,我们经常写模板函数接收不同类型的参数。

如果你希望它既能传递左值又能传递右值,那么你就需要完美转发(Perfect Forwarding)

🌟 示例:完美转发

#include <iostream>

void print(int& x) {
    std::cout << "左值引用\n";
}

void print(int&& x) {
    std::cout << "右值引用\n";
}

template<typename T>
void wrapper(T&& arg) {
    print(std::forward<T>(arg));  // 保留原始值类别
}

int main() {
    int a = 10;
    wrapper(a);      
    std::cout << "-----------\n";
    wrapper(42);     
}

执行结果:

左值引用
-----------
右值引用

核心机制:

🌱 转发引用T&&在模板中会根据传入参数的类型推导为左值引用或右值引用。

🌱 std::forward<T>(arg) 的作用:将 arg 按照 T 的值类别原样传递。

注意:

不要在非模板函数中使用T&&,因为它只是普通的右值引用。

🧩小结

  • std::move 的本质是类型转换:将左值强转为右值,以触发移动操作
  • std::forward 的本质是条件转发:保留原始值类别,实现完美转发

希望本文对你有帮助~

本文首发于微信公众号《Linux在秋名山》,欢迎大家关注~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Linux在秋名山

您的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值