移动构造函数与移动赋值
Move constructor vs. Move assignment
作为 问题的扩展,我正在努力使我的移动分配正确。
我有以下代码:
// copy assignment operator
LinkedList<T>& operator= (LinkedList<T> other) noexcept
{
swap(*this, other);
return *this;
}
// move assignment operator
LinkedList<T>& operator= (LinkedList<T>&& other) noexcept
{
swap(*this, other);
return *this;
}
但是当我尝试使用它时,我的代码无法编译。
首先是一些代码:
LinkedList<int> generateLinkedList()
{
LinkedList<int> List;
List.add(123);
return List;
}
int main()
{
LinkedList<int> L;
L = generateLinkedList();
^ get an error here...
我收到以下错误:
main.cpp(24): error C2593: 'operator =' is ambiguous
linkedlist.h(79): note: could be 'LinkedList &LinkedList::operator =(LinkedList &&) noexcept'(Points to the move assignment operator)
linkedlist.h(63): note: or 'LinkedList &LinkedList::operator =(LinkedList) noexcept' (Points to the copy assignment operator)
main.cpp(24): note: while trying to match the argument list '(LinkedList, LinkedList)'
是我的移动赋值运算符错了,还是我用错了?
复制赋值运算符将采用 const LinkedList<T>& other
,而不是 LinkedList<T> other
。
这个
LinkedList<T>& operator= (LinkedList<T> other) noexcept
{
swap(*this, other);
return *this;
}
是如何使用 copy-and-swap 同时实现复制和移动赋值。通过重新使用复制和移动构造函数(other
是复制构造的或移动构造的),您只需将 this
替换为 other
。 other
在函数结束时死亡,并带走了 this
的旧状态。这个实现完全没问题,但是你不需要对临时对象进行第二次重载(这确实是模棱两可的)。
如果您想为复制赋值和移动赋值提供单独的复制赋值运算符,签名将为
// copy assignment operator
LinkedList<T>& operator=(const LinkedList<T>& other) noexcept
{
//...
}
// move assignment operator
LinkedList<T>& operator=(LinkedList<T>&& other) noexcept
{
//...
}
但是因为您已经有了 swap
和复制+移动构造函数,所以最好使用复制和交换。
PS:由于这些似乎是内联定义(即在 class 主体内),您可以跳过 <T>
模板参数 - 在 LinkedList
模板内class定义,写成LinkedList
自动指代"current instantiation"(即LinkedList<T>
)。
作为
我有以下代码:
// copy assignment operator
LinkedList<T>& operator= (LinkedList<T> other) noexcept
{
swap(*this, other);
return *this;
}
// move assignment operator
LinkedList<T>& operator= (LinkedList<T>&& other) noexcept
{
swap(*this, other);
return *this;
}
但是当我尝试使用它时,我的代码无法编译。
首先是一些代码:
LinkedList<int> generateLinkedList()
{
LinkedList<int> List;
List.add(123);
return List;
}
int main()
{
LinkedList<int> L;
L = generateLinkedList();
^ get an error here...
我收到以下错误:
main.cpp(24): error C2593: 'operator =' is ambiguous
linkedlist.h(79): note: could be 'LinkedList &LinkedList::operator =(LinkedList &&) noexcept'(Points to the move assignment operator)
linkedlist.h(63): note: or 'LinkedList &LinkedList::operator =(LinkedList) noexcept' (Points to the copy assignment operator)
main.cpp(24): note: while trying to match the argument list '(LinkedList, LinkedList)'
是我的移动赋值运算符错了,还是我用错了?
复制赋值运算符将采用 const LinkedList<T>& other
,而不是 LinkedList<T> other
。
这个
LinkedList<T>& operator= (LinkedList<T> other) noexcept
{
swap(*this, other);
return *this;
}
是如何使用 copy-and-swap 同时实现复制和移动赋值。通过重新使用复制和移动构造函数(other
是复制构造的或移动构造的),您只需将 this
替换为 other
。 other
在函数结束时死亡,并带走了 this
的旧状态。这个实现完全没问题,但是你不需要对临时对象进行第二次重载(这确实是模棱两可的)。
如果您想为复制赋值和移动赋值提供单独的复制赋值运算符,签名将为
// copy assignment operator
LinkedList<T>& operator=(const LinkedList<T>& other) noexcept
{
//...
}
// move assignment operator
LinkedList<T>& operator=(LinkedList<T>&& other) noexcept
{
//...
}
但是因为您已经有了 swap
和复制+移动构造函数,所以最好使用复制和交换。
PS:由于这些似乎是内联定义(即在 class 主体内),您可以跳过 <T>
模板参数 - 在 LinkedList
模板内class定义,写成LinkedList
自动指代"current instantiation"(即LinkedList<T>
)。