什么时候引用是右值引用?
When is a reference an Rvalue reference?
我玩这个例子是为了理解右值引用:
#include <string>
#include <iostream>
#include <utility>
#include <vector>
class Dog
{
public:
Dog() {};
Dog(Dog&& a) { std::cout << "R value" << std::endl;}
};
Dog foo()
{
return Dog();
}
int main()
{
std::vector<Dog> v;
v.push_back(Dog()); // calls move constructor
Dog c((Dog())); // does not call move constructor
Dog d(foo()); // does not call move constructor
}
我很难理解为什么在行 v.push_back(Dog()) 中,对象 Dog() 被视为右值(因此调用了移动构造函数),但以下两行不调用移动构造函数。我想我可能在这里误解了匿名对象和 RValue 之间的关系。
这是因为Return Value Optimization。你的编译器足够聪明,可以看到最后两行可以简化为:
Dog c;
Dog d;
所以只允许将您的代码重写为上面的代码。由于 push_back
不符合允许 RVO 的要求,因此创建了一个临时文件并像您所看到的那样简单地移动了。尝试向构造函数中添加打印,它会变得更清晰。
我玩这个例子是为了理解右值引用:
#include <string>
#include <iostream>
#include <utility>
#include <vector>
class Dog
{
public:
Dog() {};
Dog(Dog&& a) { std::cout << "R value" << std::endl;}
};
Dog foo()
{
return Dog();
}
int main()
{
std::vector<Dog> v;
v.push_back(Dog()); // calls move constructor
Dog c((Dog())); // does not call move constructor
Dog d(foo()); // does not call move constructor
}
我很难理解为什么在行 v.push_back(Dog()) 中,对象 Dog() 被视为右值(因此调用了移动构造函数),但以下两行不调用移动构造函数。我想我可能在这里误解了匿名对象和 RValue 之间的关系。
这是因为Return Value Optimization。你的编译器足够聪明,可以看到最后两行可以简化为:
Dog c;
Dog d;
所以只允许将您的代码重写为上面的代码。由于 push_back
不符合允许 RVO 的要求,因此创建了一个临时文件并像您所看到的那样简单地移动了。尝试向构造函数中添加打印,它会变得更清晰。