为什么为向量 emplace 调用复制构造函数,而不为 set 调用复制构造函数?

时间:2021-07-20 01:37:33

标签: c++ c++17

这是我在 emplace 上的简单程序。 当我在向量上使用 emplace 时,我看到复制构造函数被调用。 但是,当我在现场使用 emplace 时,我没有看到调用了复制构造函数。 我在这里缺少什么概念?

#include <iostream>
#include <vector>
#include <set>

using namespace std;


class MyData
{
    private:
        int x;
    public:
        int getX()
        {
           return x;
        }
        MyData(int val): x(val) { cout<<"Constructor invoked--"<<endl; }
        MyData(const MyData &rhs) { cout<<"Copy Constructor Invoked"<<endl; x = rhs.x; } 
                bool operator<(const MyData &lhs) const  { return lhs.x < x; }
};


int main(int argc, char **argv)
{
  
  MyData d1(5);
  cout<<d1.getX()<<endl;

  vector<MyData> vx;
  auto it = vx.begin();
  vx.insert(it,d1);
  cout<<"Calling emplace for vector"<<endl;
  vx.emplace_back(15);

  set<MyData> mySet;
  cout<<"mySet emplace invoking"<<endl;
  mySet.emplace(20);
  return 0;
}

这是我的结果。

./emplace.out 
Constructor invoked--
5
Copy Constructor Invoked
Calling emplace for vector
Constructor invoked--
Copy Constructor Invoked
mySet emplace invoking
Constructor invoked--

1 个答案:

答案 0 :(得分:1)

根据定义,向量中的所有值都必须在连续内存中。向向量添加值意味着,每一次在一个值中,向量中的所有值都会重新分配以容纳更多值。每次重新分配都会为进一步增长保留额外的内存,一旦额外的值用完,向量就会再次重新分配。这是向量工作原理的简要总结。

在这种情况下,在调用 emplace() 之前,向量中已经有一个值。

额外的复制构造实际上是向量重新分配其内容(一个现有值)的结果,作为 emplace() 在向量中创建新值的一部分。这是通过复制构造重新分配的向量中的值来完成的。

std::set 不会重新分配其内容,因此这些都不会发生。

相关问题