【发布时间】:2014-02-18 06:45:52
【问题描述】:
我尝试了以下代码:
#include <iostream>
struct test{
test(){}
test(test const &){
std::cout<<__LINE__<<"\n";
}
test(test&&){
std::cout<<__LINE__<<"\n";
}
};
#include <vector>
#include <utility> // std::move
int main(){
auto&& tmp = test();
std::vector<test> v;
v.push_back(tmp);
std::cout<<__LINE__<<"\n";
v.push_back(std::move(tmp));
return 0;
}
vs2013 编译器输出:
6 // 复制
18
9 // 移动
9 // 移动
g++ 和 clang++ 输出:
6 // 复制
18
9 // 移动
6 // 复制
我的问题是:
tmp的类型是test&&吗? tmp 是右值吗?
如果tmp的类型是test&&,为什么第一个push_back没有使用move构造函数?
最后的输出是从哪里来的?为什么 vs2013 和 g++ 输出的结果不一样?
谢谢。
第三个问题的答案: 它来自 andrew.punnett 评论的重新分配。
【问题讨论】:
-
我已经修改了我的答案以扩展 Andrew 的评论。
-
最有效的解决方案是
v.emplace_back();,它既不需要复制也不需要移动。 -
注意:
v.emplace_back()确实会移动对象,如果它是在调用之前构造的 -
@DarkWanderer
v.emplace_back();在向量内存中直接构造对象。调用之前没有创建对象。 -
@FredOverflow:不。
MyClass instance; v.emplace_back(instance);。虽然我的移动是错误的,但它会通过复制构造函数进行复制。