4

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!

spec
  • 61
  • 4

0 Answers0