【发布时间】:2020-07-19 11:18:16
【问题描述】:
我正在阅读 Stroustrup 的书(第 4 版)并看到了这个例子:
template<typename T, typename A = allocator<T>>
struct vector_base { // memory structure for vector
A alloc; // allocator
T* elem; // start of allocation
T* space; // end of element sequence, start of space allocated for possible expansion
T* last; // end of allocated space
vector_base(const A& a, typename A::size_type n, typename A::size_type m =0)
: alloc{a}, elem{alloc.allocate(n+m)}, space{elem+n}, last{elem+n+m} { }
~vector_base() { alloc.deallocate(elem,last-elem); }
vector_base(const vector_base&) = delete; // no copy operations
vector_base& operator=(const vector_base&) = delete;
vector_base(vector_base&&); // move operations
vector_base& operator=(vector_base&&);
};
template<typename T, typename A>
vector_base<T,A>::vector_base(vector_base&& a)
: alloc{a.alloc},
elem{a.elem},
space{a.space},
last{a.last}
{
a.elem = a.space = a.last = nullptr; // no longer owns any memory
}
template<typename T, typename A>
vector_base<T,A>& vector_base<T,A>::operator=(vector_base&& a)
{
swap(*this,a);
return *this;
}
来自this answer,我了解到您不能只在赋值运算符中使用std::swap(*this, other),因为std::swap 通常是根据赋值运算符本身来实现的。因此,您首先需要提供自己的自定义swap 函数。
这是一个错误,还是我遗漏了什么?
【问题讨论】:
-
如果您不提供自己的交换,您可能会得到一个“通用”效率较低的交换。
-
@Eljay 这不是我所理解的。如果通用交换执行
T tmp = a; a = std::move(b); b = std::move(tmp);,那么a和b的移动分配将依次再次调用swap,无休止,对吧? -
那也是个问题。就像在赋值方面实现赋值的代码一样。
-
在 C++ 中可以通过不同的方式实现很多东西,因此请仔细阅读以确保您所使用的部分可以协同工作。