根据我的理解,当向量增加其容量时,它会分配一个新内存,将所有内容复制(移动?)到新数组,然后销毁旧数据:
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 |
+---------+
在上面的示例中,从move
到0x4b16d0
的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被调用,它仍然会将数据从一个地方复制到另一个地方,是吗?
如果是这样,这是否意味着当向量使用移动语义增加其容量时,它根本不会提高性能?
答案 0 :(得分:1)
你的矢量是vector<int>
。移动int
与复制它是一样的,因此这里没有“性能提升”。
如果您有vector<std::string>
,那么您会注意到差异;大字符串将从旧内存位置移动到新内存位置。这将比在新位置复制构造新字符串并破坏旧字符串更快。
(正如Chris Beck所指出的,只有移动构造函数不能抛出对象时才会移动对象,但我相信std::string
}就是这种情况。
我不确定您在foo
示例中尝试测试的内容,因为foo
实际上并不包含任何数据。