我正在学习C++11,关于移动语义和右值引用,我有一个问题。我的示例代码如下(C++ Shell URL为 cpp.sh/8gt):
这是结果:
但是,如果我将
#include <iostream>
#include <vector>
void aaa(std::vector<int>&& a)
{
std::cout << "size of a before move: " << a.size() << std::endl;
std::vector<int> v;
v = a; /*std::move(a)*/
std::cout << "size of a after move: " << a.size() << std::endl;
}
int main ()
{
std::vector<int> foo (3,0);
aaa(std::move(foo));
return 0;
}
这是结果:
size of a before move: 3
size of a after move: 3
在函数aaa的第v = a
行,似乎std :: vector的移动分配运算符没有被调用,否则a将具有大小0而不是3。但是,如果我将
v = a
更改为v = std :: move(a)
,输出将变为
移动前a的大小:3
移动后a的大小:0
我认为这次已经调用了std :: vector的移动分配运算符。
我的问题是为什么第一次未调用分配运算符? 根据c ++参考,std :: vector具有接受右值引用的分配运算符。
复制(1)vector& operator =(const vector& x);
移动(2)vector& operator =(vector&& x );
初始值设定项列表(3)vector& operator =(initializer_list il);
然后在v = a
行,由于a声明为右值引用,应当调用移动运算符。 为什么我们仍然需要使用std :: move包装a?
非常感谢!
[编辑] 我认为Loopunroller和Kerrek SB都回答了我的问题。 谢谢! 我不认为我可以选择两个答案,所以我会选择第一个。
v = a
将会默默地修改a
,导致正是移动语义旨在避免的auto_ptr
风格的怪异行为。 - Mike Seymour