4

I'm reading Stroustrup's book (4th ed) and saw this example:

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

From this answer, I understand that you can't just std::swap(*this, other) in an assignment operator because std::swap is often implemented in terms of the assignment operator itself. Therefore, you first need to provide your own custom swap function.

Is this a mistake, or am I missing something?

Martin
  • 940
  • 6
  • 26
  • If you don't provide your own swap, you may get a "generic" less efficient swap. – Eljay Jun 27 '20 at 21:15
  • 1
    @Eljay that's not what I understood. If the generic swap does `T tmp = a; a = std::move(b); b = std::move(tmp);`, then the move assignments of `a` and `b` would in turn call `swap` again, endlessly, right? – Martin Jun 27 '20 at 21:26
  • Then that would be a problem, too. Like code that implements assignment in terms of assignment. – Eljay Jun 27 '20 at 21:41
  • There are many things that can be implemented different ways in C++ so do a careful reading to ensure that you take parts that works together. – Phil1970 Jun 28 '20 at 02:23

1 Answers1

1

Looks like this is a duplicate of Usage of std::swap() inside move assignment should cause endless recursion (and causes), but it is an example from Stroustrup's book. Seems like Stroustrup does define a custom swap function; I seem to have missed it.

EDIT: I haven't found the swap function. Seems like it's a mistake on the book.

Martin
  • 940
  • 6
  • 26