Son*_*ong 6 c++ stdvector rvalue-reference move-semantics c++11
我正在学习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;
}
Run Code Online (Sandbox Code Playgroud)
结果是:
Run Code Online (Sandbox Code Playgroud)size of a before move: 3 size of a after move: 3
这似乎性病::向量的线,则不会调用的移动赋值运算符v = a
的功能aaa
,否则a
将有大小为0,而不是3.
但是,如果我改变v = a
对v = std::move(a)
输出成为
前移动的
大小:后移动的3个大小:0
我瘦了这次调用std :: vector的move赋值运算符.
我的问题是为什么第一次不调用assign运算符?根据c ++参考,std :: vector有一个赋值运算符,它接受一个右值引用.
copy(1)vector&operator =(const vector&x);
move(2)vector&operator =(vector && x);
initializer list(3)vector&operator =(initializer_list il);
然后在行v = a
,因为a被声明为rvalue引用,所以应该调用move运算符.为什么我们仍然需要使用std :: move包装?
提前谢谢了!
[编辑]我认为Loopunroller和Kerrek SB都回答了我的问题.谢谢!我不认为我可以选择两个答案,所以我会选择第一个答案.
Col*_*mbo 11
[expr]/6中的这一说明可能会澄清正在发生的事情(强调我的):
[ 注意:表达式是xvalue,如果它是:
- 调用函数的结果,无论是隐式还是显式,其返回类型是对象类型的右值引用,
- 强制转换为对象类型的右值引用,
- 一个类成员访问表达式,指定非引用类型的非静态数据成员,其中对象表达式是xvalue,或者
- 一个
.*
指针到构件表达,其中第一操作数是一个x值和第二个操作数是一个指向数据成员.通常,此规则的作用是将命名的右值引用视为左值,将对象的未命名右值引用视为xvalues; 对函数的右值引用被视为左值,无论是否命名.- 结束说明 ]
std::move(a)
根据上面的列表(第一项),不难看出表达式是xvalue.
a
是左值引用的名称,因此是左值作为表达式.
表达式a
是左值.表达式std::move(a)
是一个右值.只有rvalues绑定到rvalue引用,它们组成了移动构造函数和移动赋值运算符.
值得重复这一点直到它有意义:评估任何引用变量,并且还取消引用任何可解除引用的指针,产生左值.
归档时间: |
|
查看次数: |
1665 次 |
最近记录: |