移动构造函数与移动分配

tan*_*nic 1 c++ move-assignment-operator

作为问题的扩展,我正在尝试正确设置我的移动分配。

我有以下代码:

// 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;
}
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试使用它时,我的代码无法编译。

首先一些代码:

LinkedList<int> generateLinkedList()
{
    LinkedList<int> List;   
    List.add(123);
    return List;
}


int main()
{
    LinkedList<int> L;   
    L = generateLinkedList();
      ^ get an error here...
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

main.cpp(24):错误C2593:'operator ='不明确

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

linkedlist.h(63):注意:或'LinkedList&LinkedList :: operator =(LinkedList)noexcept'(指向副本分配运算符)

main.cpp(24):注意:在尝试匹配参数列表'(LinkedList,LinkedList)'时

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

Max*_*hof 5

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

这个

LinkedList<T>& operator= (LinkedList<T> other) noexcept
{
    swap(*this, other);
    return *this;
}
Run Code Online (Sandbox Code Playgroud)

是一种使用copy-and-swap同时实现复制和移动分配的方式。通过重复使用copy和move构造函数(other可以是复制构造的或move构造的),只需this与交换即可otherother死在函数的末尾,并带有的旧状态this。此实现完全可以,但是您不需要为临时对象再添加第二个过载(这确实是模棱两可的)。

如果要为复制与移动分配提供单独的复制分配运算符,则签名应为

// copy assignment operator
LinkedList<T>& operator=(const LinkedList<T>& other) noexcept
{
  //...
}

// move assignment operator
LinkedList<T>& operator=(LinkedList<T>&& other) noexcept
{
  //...
}
Run Code Online (Sandbox Code Playgroud)

但是由于您已经拥有swap了copy + move构造函数,因此最好使用copy-and-swap。

PS:由于这些似乎是内联定义(即在类主体内),因此可以跳过<T>模板参数-在LinkedList模板类定义内,LinkedList自动编写是指“当前实例化”(即LinkedList<T>)。