为什么调用复制构造函数而不是移动构造函数?

Why is copy constructor called rather than move constructor?

我有以下代码:

#include <bits/stdc++.h>

using namespace std;

class A {
public:
    A(const A& a) noexcept { cout << "copy constructor" << endl; }
    A& operator=(const A& a) noexcept { cout << "copy assignment operator" << endl; }
    A(A&& a) noexcept { cout << "move constructor" << endl; }
    A& operator=(A&& a) noexcept { cout << "move assignment operator" << endl; }
    A() { cout << "default constructor" << endl; }
};

vector<A> aList;

void AddData(const A&& a)
{
    aList.push_back(std::move(a));
}

int main()
{
    AddData(A());
    return 0;
}

输出为default constructor copy constructor。请告诉我右值引用 push_back(T&&) 被调用了吗?什么时候调用复制构造函数?

问题出在 AddData() 中的 a 参数:

void AddData(const A&& a) // <-- const reference!!!
{
    aList.push_back(std::move(a)); // selects push_back(const A&)
}

上面的a参数是一个const右值引用。您正在用 std::move() 标记一个 const 对象。

std::move() 标记 const 对象进行移动在移动语义方面没有任何效果,因为您不能从 const 对象移动(即,您需要更改移出的对象,但它是 const 限定的)。

右值引用不绑定到 const 对象,但 const 左值引用绑定。结果,选择了 push_back(const A&) 重载而不是 push_back(A&&) 重载,因此 A 对象是复制构造的。


解决方案

改用非const右值引用:

void AddData(A&& a) // <-- non-const reference
{
    aList.push_back(std::move(a)); // selects push_back(A&&)
}