explorer

万丈高楼平地起,勿在浮沙筑高台

0%

声明一个右值引用,使用T&&这种格式,但是这玩意并不是表面上看到的那么简单。

1
2
3
4
5
6
7
void f(Widget&& param);             // 右值引用
Widget&& var1 = Widget(); // 右值引用
auto&& var2 = var1; // 通用引用
template<typename T>
void f(std::vector<T>&& param); // 右值引用
template<typename T>
void f(T&& param); // 通用引用
阅读全文 »

当形参被声明为右值引用时,意味着传入的实参需要是右值引用,并且该参数是可移动的。既然目的如此明确,那么使用std::move是正确的选择:

1
2
3
4
5
6
7
8
9
10
11
class Widget {
public:
Widget(Widget&& rhs) // rhs is rvalue reference
: name(std::move(rhs.name)),
p(std::move(rhs.p))
{ … }

private:
std::string name;
std::shared_ptr<SomeDataStructure> p;
};
但如果形参被声明为通用引用时,则意味着实参有可能是右值引用,该参数有可能可被移动。那么对应的使用std::forward是正确的选择:
1
2
3
4
5
6
7
class Widget {
public:
template<typename T>
void setName(T&& newName) // newName is
{ name = std::forward<T>(newName); } // universal reference

};

阅读全文 »

需要时刻牢记的是:函数的形参都是左值,即使它的类型是右值引用,它也是左值,因为它可以被取地址。

主要是区分什么是右值,满足以下二者之一即可: 1. 临时对象 2. 无法位于赋值符号右边的对象

阅读全文 »