C++ 在move赋值中使用std::swap()应该会导致无休止的递归(并导致),但这是Stroustrup';书

C++ 在move赋值中使用std::swap()应该会导致无休止的递归(并导致),但这是Stroustrup';书,c++,c++11,recursion,move-semantics,C++,C++11,Recursion,Move Semantics,我试图深入了解如何编写复制和移动构造函数以及赋值运算符 Bjarne Stroustrup的“C++编程语言- 2013”中,我看到下面的移动构造函数和移动赋值的例子: 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.spa

我试图深入了解如何编写复制和移动构造函数以及赋值运算符

Bjarne Stroustrup的“C++编程语言- 2013”中,我看到下面的移动构造函数和移动赋值的例子:

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;
}
我已经检查过了,这里有一个非常简单的程序:

#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);
   }
}

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

您缺少的是strousTrup在与类相同的命名空间中提供了一个免费函数
swap(TestA&,TestA&)

此外,他不将其称为
std::swap
(您的代码也不这样),而是使用一个非限定id,并将
std::swap
注入命名空间中,使用
using::std::swap

这意味着不使用标准提供的通用版本


至少应该是这样。似乎真正缺少独立的
swap()
。哎哟。

您缺少的是Stroustroup在与类相同的命名空间中提供了一个免费函数
swap(TestA&,TestA&)

此外,他不将其称为
std::swap
(您的代码也不这样),而是使用一个非限定id,并将
std::swap
注入命名空间中,使用
using::std::swap

这意味着不使用标准提供的通用版本


至少应该是这样。似乎真正缺少独立的
swap()
。哎哟。

你没有遗漏任何东西,公认的答案是错误的。斯特劳斯特鲁普的书简直糟透了。第13章中没有独立的
swap()
;强烈暗示这
swap()
std::swap()
(就像
copy()
std::copy()
,等等)。这只是一只虫子。欢迎来到C++。

< p>你没有错过任何东西,而被接受的答案是错误的。斯特劳斯特鲁普的书简直糟透了。第13章中没有独立的
swap()
;强烈暗示这
swap()
std::swap()
(就像
copy()
std::copy()
,等等)。这只是一只虫子。欢迎使用C++。<代码>最后{ASPACE } /CODE在<代码> VCCTRESION基础< /COD>的移动构造函数中看起来是错误的——不应该是代码>最后{A.最后} <代码> >不,<代码>空间< /C>是一个结构成员,这里有一个定义:<代码>最后{A.Stule}
vector_base
的move构造函数中,它看起来是错误的——它不应该是
last{a.last}
不,
空间是一个结构成员,下面是它的定义:谢谢,听起来不错,但我刚刚试图在我的pdf书籍文件中找到免费函数
swap()
,但我没有找到它。这是不是很明显,甚至不值得一提书中的代码是否在赋值运算符中将参数作为
vector\u base&
?复制和交换习惯用法通常使用一个值参数。@0x499602D2,是的,当然我刚刚复制粘贴了代码。它在第379页,第13.6.2节。它应该在书中的某个地方。但我无法验证,还没有。@Deduplicator,仅供参考:没有,至少我和我的pdf查看器没有找到它。再次感谢您的回答。谢谢,听起来不错,但我刚刚试图在我的pdf书籍文件中找到免费函数
swap()
,但我没有找到它。这是不是很明显,甚至不值得一提书中的代码是否在赋值运算符中将参数作为
vector\u base&
?复制和交换习惯用法通常使用一个值参数。@0x499602D2,是的,当然我刚刚复制粘贴了代码。它在第379页,第13.6.2节。它应该在书中的某个地方。但我无法验证,还没有。@Deduplicator,仅供参考:没有,至少我和我的pdf查看器没有找到它。再次感谢你的回答。
#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);
   }
}
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
...
...