首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >c++ - NRVO和move

c++ - NRVO和move
EN

Stack Overflow用户
提问于 2017-06-06 09:00:53
回答 2查看 481关注 0票数 1

我读过几篇关于move函数(例如http://www.cprogramming.com/c++11/rvalue-references-and-move-semantics-in-c++11.html)的文章,我想观察一下move操作符的运行情况。因此,我尝试了以下代码:

代码语言:javascript
复制
#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;
}

我希望为局部变量resultc获得相同的地址,因为移动运算符是为vector实现的。我得到了准确的结果,但不管有没有国旗-std=c++11。这就是我了解NRVO (c++11 Return value optimization or move?)的时候,所以我用标志-fno-elide-constructors禁用了它,现在地址已经不同了,甚至是标志-std=c++11。我的代码有问题吗?还是我理解了移动操作符的错误?

据我所理解,返回值应该足以让move操作符启动(C++11 rvalues and move semantics confusion (return statement))。

PS:我尝试了GCC 6.3.0_1和Apple版本8.1.0。

编辑

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-06-06 09:12:50

将移动视为优化的副本。它仍然是一个副本,所以它仍然是一个不同的向量,但它将底层数据从一个向量“移动”到另一个向量。通过比较数据的地址可以看出这一点:

代码语言:javascript
复制
cout<<result.data()<<endl;

代码语言:javascript
复制
cout<<c.data()<<endl;

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

票数 2
EN

Stack Overflow用户

发布于 2017-06-06 09:10:34

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

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44385691

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档