左值和右值

左值的英文简写为“lvalue”,右值的英文简写为“rvalue”。很多人认为它们分别是"left value"、“right value” 的缩写,其实不然。lvalue 是“loactor value”的缩写,可意为存储在内存中、有明确存储地址(可寻址)的数据,而 rvalue 译为 “read value”,指的是那些可以提供数据值的数据(不一定可以寻址,例如存储于寄存器中的数据)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 左值引用
int num = 10;
int &b = num; // 正确
int &c = 10; // 错误

int num = 10;
const int &b = num; // 正确
const int &c = 10; // 正确


// 右值引用
int num = 10;
//int && a = num; // 错误,右值引用不能初始化为左值
int && a = 10; // 正确

a = 100;
cout << a << endl; // 输出为100,右值引用可以修改值


// 右值引用的使用
// 如 thread argv 的传入
template<typename _Callable, typename... _Args>
explicit thread(_Callable&& __f, _Args&&... __args) {
//....
}
// Args&&... args 是对函数参数的类型 Args&& 进行展开
// args... 是对函数参数 args 进行展开
// explicit 只对构造函数起作用,用来抑制隐式转换

(2条消息) C++ 左值和右值_TABE_的博客-CSDN博客_左值和右值

讲的非常好

可变参数

(2条消息) C中可变参数…args_wodownload2的博客-CSDN博客_c args…

(2条消息) C11 ——— 可变参数模板_2021dragon的博客-CSDN博客_c11 可变参数模板

(2条消息) 理解std::move和std::forward_土戈的博客-CSDN博客_std::forward

C++ move && forward

std::move

c++11中提供了std::move()来将左值转换为右值引用,从而方便的使用移动语义。move是将对象的状态或者所有权从一个对象转移到另一个对象,只是转移,没有内存拷贝。

c++中所有容器都实现了move语义,方便我们实现性能优化。move对于拥有形如对内存、文件句柄等资源的成员的对象有效。如果是一些基本类型,比如int或char[10]数组等,如果使用move,仍然会发生拷贝(因为没有对应的移动构造函数)。

1
2
3
std::list<std::string> tokens;
// 发生了移动构造。list的实现,将目的资源句柄赋值为源资源句柄,而将源资源句柄清空
std::list<std::string> t = std::move(tokens);

std::forward

右值引用类型是独立于值的,一个右值引用参数作为函数的形参,在函数内部再转发该参数的时候它已经变成一个左值,并不是他原来的类型。

需要一种方法能够按照参数原来的类型转发到另一个函数,这种转发类型称为完美转发

完美转发(Perfect Forwarding),是指在函数模板中,完全依照模板的参数的类型(即保持参数的左值、右值特征),将参数传递给函数模板中调用的另外一个函数。C++11中提供了这样的一个函数std::forward,它是为转发而生的,不管参数是T&&这种未定的引用还是明确的左值引用或者右值引用,它会按照参数本来的类型转发。

tuple

(2条消息) C的tuple_物随心转的博客-CSDN博客_c tuple

C++模板 - index_sequence

(2条消息) C++模板 - index_sequence_AMjieker的博客-CSDN博客_std::index_sequence

// vector.reserve() 更改vector的容量(capacity),使vector至少可以容纳n个元素。

// 如果n大于vector当前的容量,reserve会对vector进行扩容。其他情况下都不会重新分配vector的存储空间