简体   繁体   中英

multiple emplace_back calling copy constructor additionally

Consider the below example :

#include <iostream>
#include <vector>

class S {
public:
  S() { puts("S()"); }
  S(int) { puts("S(int)"); }
  ~S() { puts("~S()"); }
  S(const S &) { puts("S(const S&)"); }
  S(S &&) { puts("S&&"); }
  const S &operator=(const S &s) {
    puts("=");
    return s;
  }
  S &operator=(S &&s) {
    puts("Move =");
    return s;
  }
};

int main() {
  std::vector<S> s;
  s.emplace_back();
  s.emplace_back(6);
}

O/p :

S()
S(int)
S(const S&)
~S()
~S()
~S()

When only one element is emplaced_back , the constructor/destructor pair are called exactly once. But when there are multiple emplace_back (like s.emplace_back(6); ), the copy constructor is also called. Why is this behavior difference ? is there still a copy exists with emplace_back ?

Take into account that std::vector sometimes enlarges it's allocated area (when you add to many elements) and must copy old values over to new positions. This cause the call of the copy constructor.

You can call reserve()

std::vector<S> s;
s.reserve(20);
s.emplace_back();
s.emplace_back(6);

to say the s vector has to reserve a larger memory area to avoid relocations of elements.

This is because reallocation happens as explained by @max66. As for why it is the copy constructor being called, it is because your move constructor is not noexcept .

Change to this:

S(S &&) noexcept { puts("S&&"); }

Then it's the move constructor being called.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM