移动构造函数与移动赋值

Move constructor vs. Move assignment

本文关键字:移动 赋值 构造函数      更新时间:2023-10-16

作为这个问题的扩展,我正在尝试使我的移动作业正确。

我有以下代码:

// 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(: 错误 C2593:"运算符 ="不明确

linkedlist.h(79(:注意:可以是"LinkedList &LinkedList::operator =(LinkedList &&( noexcept'(指向移动赋值运算符(

linkedlist.h(63(:注意:或 'LinkedList &LinkedList::operator =(LinkedList( noexcept' (指向复制赋值运算符(

main.cpp(24(: 注意:在尝试匹配参数列表"(链接列表,链接列表("时

我的移动分配运算符是错误的,还是我以错误的方式使用它?

复制赋值运算符将采用const LinkedList<T>& other,而不是LinkedList<T> other

LinkedList<T>& operator= (LinkedList<T> other) noexcept
{
swap(*this, other);
return *this;
}

是使用复制和交换同时实现复制和移动分配的方式。通过重用复制和移动构造函数(other是复制构造的或移动构造的(,您只需将thisother交换即可。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:由于这些似乎是内联定义(即在类体内(,您可以跳过<T>模板参数 - 在LinkedList模板类定义中,编写LinkedList会自动引用"当前实例化"(即LinkedList<T>(。