2

In the C++ example below:

#include <vector>
#include <string>
#include <iostream>

using namespace std;

struct foo{
  foo(int i) : s( to_string(i) ){ cout << "init foo : "+s+"\n"; }
  foo(foo&& f) : s( move(f.s) ){ cout << "move foo : "+s+"\n"; }
  foo(const foo& f) : s(f.s){ cout << "copy foo : "+s+"\n"; }
  string s;
};

int main(){
  vector<foo> f;
  for(int i=0; i<5; i++){
    cout << f.size() << endl;
    f.push_back( foo(i) );
  }
}

The output is :

0
init foo : 0
move foo : 0
1
init foo : 1
move foo : 1
copy foo : 0
2
init foo : 2
move foo : 2
copy foo : 0
copy foo : 1
3
init foo : 3
move foo : 3
4
init foo : 4
move foo : 4
copy foo : 0
copy foo : 1
copy foo : 2
copy foo : 3

It seems that std::vector will call the copy constructor for all foo elements in the container every time it changes its capacity.

Is there any way to force the use of move constructor instead of the copy constructor?

I do not know the final size of the vector so vector::reserve is not a possible choice.

ztik
  • 3,482
  • 16
  • 34

1 Answers1

2

You need to state that your move constructor will not throw

foo(foo&& f) noexcept  : s(move(f.s)) { cout << "move foo : " + s + "\n"; }
Marco A.
  • 43,032
  • 26
  • 132
  • 246