#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没有使用移动构造函数?
最后一个输出来自哪里?为什么vs2013和g++输出结果不同?
谢谢。
第三个问题的答案:
正如andrew.punnett所评论的那样,它来自重新分配。
v.emplace_back();
,它既不需要复制也不需要移动。 - fredoverflowv.emplace_back()
之前已经构造了对象,则该操作会移动该对象。 - DarkWandererv.emplace_back();
在向量的内存中直接构造对象,调用之前没有创建任何对象。 - fredoverflowMyClass instance; v.emplace_back(instance);
。虽然我关于移动的想法是错误的,但这将通过复制构造函数进行复制。 - DarkWandereremplace_back
。只需直接写v.emplace_back();
,括号内不需要任何内容。 - fredoverflow