c ++ - NRVO和移动

时间:2017-06-06 09:00:54

标签: c++ c++11 move nrvo

我已经阅读了一些关于移动函数的帖子(例如http://www.cprogramming.com/c++11/rvalue-references-and-move-semantics-in-c++11.html),我想观察移动运算符的运行情况。所以我尝试了以下代码:

ng build --base-href

我期望为局部变量#include <vector> #include <cassert> #include <functional> #include <algorithm> #include <iostream> using namespace std; vector<double> operator+(const vector<double>& a, const vector<double>& b){ assert(a.size()==b.size()); vector<double> result(a.size(),0); transform (a.begin(), a.end(), b.begin(), result.begin(), std::plus<double>()); cout<<&result<<endl; return result; } int main(int argc, char const *argv[]) { vector<double> a,b; for (int i=0;i<10;i++){ a.push_back(i); b.push_back(1); } std::vector<double> c=a+b; cout<<&c<<endl; return 0; } result获取相同的地址,因为移动运算符是为c实现的。而且我获得了这个,但有和没有标志vector。那时我学习了NRVO(c++11 Return value optimization or move?),所以我用标志-std=c++11禁用它,现在地址不同,即使标志为-fno-elide-constructors。我的代码是否存在问题,或者我对移动运算符有什么不妥?

根据我的理解,按值返回应足以让移动操作员启动(C++11 rvalues and move semantics confusion (return statement))。

PS:我尝试使用GCC 6.3.0_1和Apple LLVM版本8.1.0。

修改

正如所指出的那样,我应该检查-std=c++11而不是result.data()(见下文)。但在这种情况下,我总是找到相同的地址,即使没有&resultstd=c++11也是如此。请参阅已接受的答案及其评论部分。

2 个答案:

答案 0 :(得分:3)

移动构造函数通过窃取旧对象的资源来构造新对象。它根本不合并临时工具:如果构造没有被省略,你仍然有两个对象。

答案 1 :(得分:2)

将移动视为优化副本。它仍然是一个副本,所以它仍然是一个不同的向量,但它有&#34;移动&#34;从一个向量到另一个向量的基础数据。您可以通过比较数据的地址来看到:

cout<<result.data()<<endl;

cout<<c.data()<<endl;

另一方面,复制省略完全取消了复制品。