https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71964

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |ASSIGNED
      Known to work|                            |4.8.4
            Version|unknown                     |4.9.4
   Last reconfirmed|                            |2016-07-22
          Component|c++                         |libstdc++
           Assignee|unassigned at gcc dot gnu.org      |redi at gcc dot gnu.org
     Ever confirmed|0                           |1
            Summary|Move constructor of         |[4.9/5/6/7 Regression] Move
                   |std::set does not move      |constructor of std::set
                   |allocator                   |does not move allocator
           Severity|normal                      |minor

--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Roland Dreier from comment #0)
> My understanding of allocator aware containers (of which std::set is one) is
> that moving the container should move the allocator.

That's not _strictly_ true. The requirement is that the new container's
allocator equals the value that the original container's allocator had before
the construction. The source object is left in a valid but unspecified state,
so it is not required to be in a moved-from state.

i.e.

int main()
{
  std::set<int, std::less<int>, my_allocator<int> > x;
  auto a = x.get_allocator();
  std::set<int, std::less<int>, my_allocator<int> > y{ std::move(x) };
  assert( y.get_allocator() == a );
}

That holds true with our implementation (once your allocator is fixed by giving
it the required my_allocator(const my_allocator<U>&) constructor needed for
rebinding it, also note that your move constructor takes a const reference
which would generally make it a useless move constructor).

For most generic code it matters whether a move or a copy is performed in a
given context, because the object might not be copyable and so only moving
would compile. But allocators are always required to be CopyConstructible, so
that doesn't apply here either.

However, strictly required or not it's reasonable to expect the move there and
is trivial to fix.


> I tried with std::vector and std::list as got the the expected "move
> constructor called".  Also gcc 4.8 std::set moves the allocator - the
> regression seems to have occurred in gcc 4.9.

Yes it happened when I added proper C++11 allocator support to the associative
containers.

Reply via email to