关于调整std :: vector大小时调用的复制构造函数与移动构造函数的混淆

时间:2015-06-24 12:43:31

标签: c++ c++11 vector constructor move-semantics

我有以下情况:包含自定义类的元组存储在向量中。

struct A {
    string m_name;

    void cp(const A& x)        { m_name = x.m_name;       cout << m_name << ": copy "; }
    void mv(A&& x)             { m_name = move(x.m_name); cout << m_name << ": move "; }

    A(const string& n) : m_name(n)          { cout << "ctor" << endl; }
    A(A&& x)                   { mv(move(x)); cout << "ctor" << endl; }
    A(const A& x)              { cp(x);       cout << "ctor" << endl; }
    A& operator=(A&& x)        { mv(move(x)); cout << "ass-op" << endl; return *this; }
    A& operator=(const A& x)   { cp(x);       cout << "ass-op" << endl; return *this; }
    ~A() noexcept              { cout << m_name << ": dtor " << endl; }
};

using t_tuple = tuple<string, A>;
vector<t_tuple> v;

void store_in_vector(const string& s, A&& a) {
    v.emplace_back(s, move(a));
}

在向量中插入元素时,我发现只要A必须在内部调整自身大小,就会调用std::vector的复制构造函数。

这是我的测试代码:

store_in_vector("a", A("a"));
store_in_vector("b", A("b"));
store_in_vector("c", A("c"));
store_in_vector("d", A("d"));
store_in_vector("e", A("e"));
store_in_vector("f", A("f"));
store_in_vector("g", A("g"));
store_in_vector("h", A("h"));
store_in_vector("i", A("i"));
store_in_vector("j", A("j"));
store_in_vector("k", A("k"));
store_in_vector("l", A("l"));

插入&#34; b&#34;后输出如下所示:元件

  

构造函数
  b:移动ctor
  a:复制ctor
  a:dtor
  :dtor

为什么要调用复制构造函数?如果std::vector调用MOVE构造函数,那么它会更优化吗?令我困惑的是以下内容:如果我将struct A更改为删除复制构造函数的以下实现,它实际上在调整向量大小时调用MOVE构造函数。

以下是struct A的修改后的实现:

struct A {
    string m_name;

    void cp(const A& x)        { m_name = x.m_name;       cout << m_name << ": copy "; }
    void mv(A&& x)             { m_name = move(x.m_name); cout << m_name << ": move "; }

    A(const string& n) : m_name(n)          { cout << "ctor" << endl; }
    A(A&& x)                   { mv(move(x)); cout << "ctor" << endl; }
    A(const A& x) = delete;
    A& operator=(A&& x)        { mv(move(x)); cout << "ass-op" << endl; return *this; }
    A& operator=(const A& x) = delete;
    ~A() noexcept              { cout << m_name << ": dtor " << endl; }
};

在插入元素&#34; b&#34;:

后显示此输出
  

构造函数
  b:移动ctor
  a:移动ctor
  :dtor
  :dtor

一切似乎都能正常工作,在我的观察中,调用移动构造函数的代码应该更加优化(即更快,更少的开销)。但是,我不明白为什么会这样。如何在不删除复制构造函数的情况下更改struct A的实现来调用移动构造函数?如果在frist版本中调用复制构造函数有任何正当理由,请解释!

我正在使用Apple LLVM 6.1的Xcode

0 个答案:

没有答案