简体   繁体   English

多个emplace_back调用副本构造函数

[英]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 : 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. 当只有一个元素为emplaced_backconstructor/destructor pair将被精确调用一次。 But when there are multiple emplace_back (like s.emplace_back(6); ), the copy constructor is also called. 但是,当有多个emplace_back (例如s.emplace_back(6); )时,也会调用copy constructor Why is this behavior difference ? 为什么这种行为有所不同? is there still a copy exists with emplace_back ? 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. 考虑到std::vector有时会扩大它的分配区域(当您添加到许多元素时),并且必须将旧值复制到新位置。 This cause the call of the copy constructor. 这导致复制构造函数的调用。

You can call reserve() 您可以致电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. s向量必须保留更大的存储区域,以避免元素重定位。

This is because reallocation happens as explained by @max66. 这是因为如@ max66所述发生重新分配。 As for why it is the copy constructor being called, it is because your move constructor is not noexcept . 至于为什么要调用拷贝构造函数,这是因为您的move构造函数不是noexcept

Change to this: 更改为此:

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

Then it's the move constructor being called. 然后是move构造函数被调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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