https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123582
--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Thomas Schwinge from comment #0)
> Consider constructing an (empty) unordered associative container 'c'
> ('std::unordered_map', 'std::unordered_multimap', 'std::unordered_multiset',
> 'std::unordered_set'), and then gradually populating it, which dynamically
> has to allocate memory for the hash table as well as the nodes.
>
> I understand that 'clear()' doesn't necessarily have to deallocate all that
> memory, but my assumption is that when overwriting such an unordered
> associative container 'c' with a pristine instance: 'c = {};', then all
> memory of 'c' should get deallocated?
No, because that is not a "pristine instance", it's an empty initializer_list,
i.e. equivalent to:
c = std::initializer_list<T>{};
This just says "replace the current elements with zero elements".
> I have not yet properly debugged
> this, but it appears as if the latter also only deallocates memory for the
> nodes, but not for the hash table? Is this intentional?
Yes, definitely.
> Is there a way to
> completely clear out an unordered associative container (other than
> destructing it)?
You can swap with a default-constructed temporary, which will restore it to a
default-constructed state.
Cont{}.swap(c);
You can usually get the same effect by move-assigning an empty object (although
depending on the properties of the container's Allocator parameter, move
assignment and swap might work differently):
c = Cont();
This really does assign a new instance of the type, which is not the same as
assigning an empty initializer_list. One is a whole container, the other is
just a syntactic notation for "this list of values".