C++11右值和右值引用相关的笔记

  1. 右值分为纯右值和将亡值:

        纯右值(prvalue):代表计算结果的值,通常是临时对象或字面值。它不与特定内存位置绑定,在表达式求值后就会被销毁。

        将亡值(xvalue):代表即将失效的对象,通常与对象的移动语义相关联。将亡值仍然与特定内存位置绑定,但这个位置即将失效,可能因为资源转移或即将销毁。

           将亡值用来触发移动构造或移动赋值运算符,并进行资源转移,之后将调用析构函数;

     从而避免了资源的重新分配 实现了移动语义。

        将亡值示例:

#include <iostream>
#include <utility>
#include <string>

int main() {
    std::string s1 = "Hello, World!";
    std::string s2 = std::move(s1);  // std::move(s1) 返回一个将亡值,并且std::move(s1)执行完之后s1会被销毁

    std::cout << "s2: " << s2 << std::endl;  // 输出: s2: Hello, World!
    std::cout << "s1: " << s1 << std::endl;  // s1 的内容是未定义的,但它仍然存在

    return 0;
}

左值还是右值是表达式的属性,和数据类型不是同一个概念:

右值引用类型的变量的属性是左值,只要是变量都是左值。

对于形参是右值引用的函数,如: void process(int&& x),调用时候重点关注的是实参的属性是不是右值,而不是实参的数据类型。

通过下面的代码理解:

#include <iostream>
#include <utility>

// 一个接受左值引用的函数
void process(int& x) {
	std::cout << "Lvalue reference called with: " << x << std::endl;
}

// 一个接受右值引用的函数
void process(int&& x) {
	std::cout << "Rvalue reference called with: " << x << std::endl;
}

 通用的包装函数,使用完美转发
template <typename T>
void wrapper(T&& arg) {
	process(std::forward<T>(arg));  // 使用 std::forward 完美转发参数
}

int main() {
	int a = 5;
	int& a1 = a;
	int&& b = 100;
	wrapper(a);	//Lvalue reference called with: 5
	wrapper(10);//Rvalue reference called with: 10
	wrapper(static_cast<int &>(a1));//Lvalue reference called with: 5
	wrapper(b);//Lvalue reference called with: 100
	wrapper(static_cast<int&&>(b));//Rvalue reference called with: 100
	wrapper(std::forward<int&&>(b)); //Rvalue reference called with : 100

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值