我偶然发现了一个奇怪的情况,即vector的emplace_back方法在可用时使用了类型的复制构造函数,即使相同的代码编译并运行正常并删除相同的复制构造函数(而是依赖于移动) )。
我能够提出一个相当简洁的例子:
using namespace std;
struct node {
vector<node> children;
node(const node&){
printf("Copy!\n");
}
node(node&&){
printf("Move!\n");
}
node(){}
node(int a) {}
};
int main(int argc, const char * argv[]) {
vector<node> vec;
node node(1);
node.children.emplace_back(2);
vec.emplace_back(move(node));
vec.emplace_back(3);
return 0;
}
对我来说这打印:
Move!
Copy!
但只是注释掉复制构造函数会导致输出:
Move!
Move!
通过调试我可以告诉副本在最终的emplace_back期间发生,所以看起来复制发生在向量的大小调整期间。实际上添加了一个&ve ;.veserve(2);&#39;消除副本(以及没有复制构造函数的第二步)
我知道这与我的节点字段的嵌入向量有关,但是为什么vector会在移动时选择复制构造函数?
这完全在:clang ++ -v
Apple LLVM 8.0.0版(clang-800.0.42.1)
目标:x86_64-apple-darwin16.1.0
- STD = C ++ 11
谢谢!