I have stumbled upon an odd case where vector's emplace_back method uses a type's copy constructor when available, even though the same code compiles and runs fine with that same copy constructor deleted (instead relying on moves).
I was able to come up with a fairly concise example:
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;
}
For me this prints:
Move!
Copy!
But simply commenting out copy constructor will lead to the output:
Move!
Move!
By debugging I can tell the copy happens during the final emplace_back, so it seems the copy happened during resizing of the vector. In fact adding a 'vec.reserve(2);' eliminates the copy (as well as the 2nd move w/ no copy constructor)
I know this has something to do with my embedded vector of node field, but why would vector ever choose a copy constructor when a move could be done?
This is all under: clang++ -v
Apple LLVM version 8.0.0 (clang-800.0.42.1)
Target: x86_64-apple-darwin16.1.0
--std=c++11
Thanks!