移动语义如何在向量重定位中起作用?

时间:2015-08-20 03:28:35

标签: c++ c++11 vector move-semantics

根据我的理解,当向量增加其容量时,它会分配一个新内存,将所有内容复制(移动?)到新数组,然后销毁旧数据:

vector<int> v;
v.emplace_back(1);
v.emplace_back(2); cout<<&v[0]<<endl; // outputs 0x4b16d0
v.emplace_back(3); cout<<&v[0]<<endl; // outputs 0x4b16f0

         +-----+  
0x4b16d0 | 1 2 |  
         +-----+  

         +---------+  
0x4b16f0 | 1 2 3   |  
         +---------+  

在上面的示例中,从move0x4b16d0的1 {和2 0x4b16f0如何?

已更新为用户定义的类

struct foo {
    foo() {}
    foo(const foo &) { cout << "copy\n"; }
    foo(foo &&) noexcept { cout << "move\n"; }
};

int main() {
    vector<foo> v;
    cout<<"1st emplace_back() \n"; v.emplace_back(); cout<<" addr of 1st element: "<<&v[0]<<endl;
    cout<<"2nd emplace_back() \n"; v.emplace_back(); cout<<" addr of 1st element: "<<&v[0]<<endl;
}

$ g++ -std=c++11 -g a.cpp; ./a.exe
1st emplace_back()
 addr of 1st element: 0x6f16d1
2nd emplace_back()
move
 addr of 1st element: 0x6f16f1

我的问题是,即使move ctor被调用,它仍然会将数据从一个地方复制到另一个地方,是吗?

如果是这样,这是否意味着当向量使用移动语义增加其容量时,它根本不会提高性能?

1 个答案:

答案 0 :(得分:1)

你的矢量是vector<int>。移动int与复制它是一样的,因此这里没有“性能提升”。

如果您有vector<std::string>,那么您会注意到差异;大字符串将从旧内存位置移动到新内存位置。这将比在新位置复制构造新字符串并破坏旧字符串更快。

(正如Chris Beck所指出的,只有移动构造函数不能抛出对象时才会移动对象,但我相信std::string}就是这种情况。

我不确定您在foo示例中尝试测试的内容,因为foo实际上并不包含任何数据。