本文介绍了在移动分配中使用std :: swap()应该导致无限递归(并导致),但这是Stroustrup的书中的一个示例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正试图获得有关如何编写副本以及移动构造函数和赋值运算符的深入知识。

I'm trying to get the deep knowledge about how should I write my copy and move constructors and assignment operators.

在Bjarne Stroustrup的 The C ++ Programming Language- 2013​​,下面是移动构造函数和移动分配的示例:

In Bjarne Stroustrup's "The C++ Programming Language - 2013" I see the following example of move constructor and move assignment:

template<class T, class A>
vector_base<T,A>::vector_base(vector_base&& a)
   : alloc{a.alloc},
   elem{a.elem},
   space{a.space},
   last{a.space}
{
   a.elem = a.space = a.last = nullptr; // no longer owns any memory
}

template<class T, class A>
vector_base<T,A>::& vector_base<T,A>::operator=(vector_base&& a)
{
   swap(∗this,a);
   return *this;
}

侧面说明:这本书似乎有错字: :::& 应该只是& ,对吧?

(Side note: there seems to be a typo in the book: ::& should be just &, right?)

我怀疑它应该引起无穷递归,因为 std :: swap()调用移动赋值运算符:

I suspected it should cause endless recursion, since std::swap() calls move assignment operator:

template<typename T>
void swap(T& lhs, T& rhs)
{
  auto temp(lhs);
  lhs = std::move(rhs);
  rhs = std::move(temp);
}

我已经检查过了,这是一个非常简单的程序:

I've checked it, here's very simple program:

#include <iostream>
using namespace std;

class TestA {
   int x;

public:
   TestA(int x = 0) : x(x) {
      cout << "TestA value ctor " << x << "\n";
   }

   ~TestA() {
      cout << "TestA dtor " << x << "\n";
   }

   TestA(const TestA &a) : x(a.x) {
      cout << "TestA copy ctor " << x << "\n";
   }

   TestA(TestA &&a) : x(a.x) {
      cout << "TestA move ctor " << x << "\n";
   }

   TestA operator=(const TestA &a) {
      x = a.getX();
      cout << "TestA copy assignment " << x << " = " << a.getX() << "\n";
      return *this;
   }

   TestA &operator=(TestA &&a) {
      cout << "TestA move assignment " << x << " = " << a.getX() << "\n";
      swap(*this, a);
      return *this;
   }

   int getX() const {
      return this->x;
   }

};

int main(void) {
   TestA a{0};
   TestA b{1};
   {
      TestA c{2};
      a = move(c);
   }
}

哪个会产生以下输出,所以我很正确无休止的递归:

Which produces the following output, so I was right about endless recursion:

TestA value ctor 0
TestA value ctor 1
TestA value ctor 2
TestA move assignment 0 = 2
TestA move ctor 0
TestA move assignment 0 = 2
TestA move ctor 0
TestA move assignment 0 = 2
TestA move ctor 0
...
...

我错过了什么吗?如何在移动分配中使用 swap()

Do I miss something? How can I use swap() inside move assignment?

推荐答案

您缺少的是Stroustroup在与该类相同的名称空间中提供了一个自由函数 swap(TestA& ;, TestA&)

What you are missing is that Stroustroup provides a free-function swap(TestA&, TestA&) in the same namespace as the class.

此外,他没有将其称为 std :: swap (您的代码也没有),但是使用了不合格的ID和 std ::的注入。使用:: std :: swap和交换到名称空间中。

Also, he does not call it as std::swap (neither does your code), but uses an unqualified id and injection of std::swap into the namespace with using ::std::swap;.

这意味着通用版本

至少应该如此。似乎真的缺少独立的 swap()。哎呀。

At least that is how it should be. Seems that free-standing swap() is really missing. Ouch.

这篇关于在移动分配中使用std :: swap()应该导致无限递归(并导致),但这是Stroustrup的书中的一个示例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-18 21:44