1

考虑下面的例子:

#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);
}

运营商/p:

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

当只有一个元素是 时emplaced_backconstructor/destructor pair只调用一次。但是当有多个emplace_back(like s.emplace_back(6);) 时,copy constructor也会调用 the 。为什么这种行为差异?emplace_back 是否仍然存在副本?

4

2 回答 2

3

这是因为按照@max66 的解释发生了重新分配。至于为什么调用的是复制构造函数,那是因为你的移动构造函数不是noexcept.

改成这样:

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

然后是被调用的移动构造函数。

于 2018-03-26T17:36:05.420 回答
3

考虑到std::vector有时会扩大它的分配区域(当您添加许多元素时)并且必须将旧值复制到新位置。这会导致复制构造函数的调用。

你可以打电话reserve()

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

s向量必须保留更大的内存区域以避免元素的重定位。

于 2018-03-26T17:33:48.873 回答