为什么调用复制构造函数而不是移动构造函数?
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&&)
}
我有以下代码:
#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&&)
}