【发布时间】:2015-08-31 20:38:34
【问题描述】:
我已经在 C++11 中测试了移动语义。我写了一个带有移动构造函数的类。
class DefaultConstructor
{
public:
DefaultConstructor(std::vector<int> test) :
m_vec(std::forward<std::vector<int>>(test))
{
};
DefaultConstructor(DefaultConstructor &&def) :
m_vec(std::forward<std::vector<int>>(def.m_vec))
{
}
DefaultConstructor& operator=(DefaultConstructor&& def) {
m_vec = std::move(def.m_vec);
return *this;
}
DefaultConstructor& operator=(const DefaultConstructor&) = delete;
DefaultConstructor(DefaultConstructor &) = delete;
std::vector<int> m_vec;
};
我编写了一个使用移动语义的主函数。我了解移动语义中发生了什么,它是一个很棒的工具。但是有些行为对我来说是无法解释的。当我为我调用主函数DefaultConstructor testConstructor2 = std::move(testConstructor); 时,应该调用DefaultConstructor& operator=(DefaultConstructor&& def)。但是 Visual Studio 2015 调用移动构造函数。
int main()
{
std::vector<int> test = { 1, 2, 3, 4, 5 };
DefaultConstructor testConstructor(std::move(test));
DefaultConstructor testConstructor2 = std::move(testConstructor);
DefaultConstructor &testConstructor3 = DefaultConstructor({ 6, 7, 8, 9 });
DefaultConstructor testConstructor4 = std::move(testConstructor3);
swapMove(testConstructor, testConstructor2);
}
好吧,我想也许 = 移动运算符不再需要了。但我尝试了一个 SwapMove 函数。此函数调用 = move 运算符。
template<typename T>
void swapMove(T &a, T &b)
{
T tmp(std::move(a));
a = std::move(b);
b = std::move(tmp);
}
有人能解释一下这两个电话之间到底有什么区别吗? a = std::move(b); 和 DefaultConstructor testConstructor2 = std::move(testConstructor); 的调用不应该具有相同的行为吗?
【问题讨论】:
-
DefaultConstructor testConstructor2 = std::move(testConstructor);是初始化,不是赋值。 -
事先单独声明
testConstructor2,例如DefaultConstructor testConstructor2({}); -
Jonatha Potter 看起来这就是答案。谢谢。
-
[OT] 你想在你的移动构造函数中使用
std::move(),而不是std::forward()。 -
没有什么要决定的,您已经明确表示
def是一个右值引用。std::forward仅在使用模板 + 引用折叠时有用。
标签: c++ c++11 move c++14 perfect-forwarding