Search code examples
c++c++17movemove-semanticsmove-constructor

std::deque is move constructible, but not 'nothrow'


The question is quite simple, summarised in the title. Is there any particular reason why this should be the case? Given that objects can efficiently swap internal state, I'm certain there's something here I'm overlooking...


Solution

  • When two deques are swapped, they are both in some valid constructed states. Consequently, swapping just requires to swap their internals, which are mostly pointers or integers (plus allocators).

    However, when you move-construct a deque, you need to get the moved-from deque into a valid state, likely the default-constructed one. This may require some operations that may throw, such as dynamic memory allocations.

    For instance, in libstdc++, deque's move constructor (as well as its default constructor) calls _Deque_base::_M_initialize_map(0). This member function allocates at least 2 "map" nodes:

    this->_M_impl._M_map_size = std::max((size_t) _S_initial_map_size,
                                  size_t(__num_nodes + 2));
    this->_M_impl._M_map = _M_allocate_map(this->_M_impl._M_map_size);
    

    In fact, it allocates at least 8 map nodes, since _S_initial_map_size is set to 8.