3778. vector<bool> missing exception specifications

Section: 23.3.12.1 [vector.bool.pspc] Status: C++23 Submitter: Alisdair Meredith Opened: 2022-09-13 Last modified: 2023-11-22

Priority: Not Prioritized

View all issues with C++23 status.

Discussion:

As noted back in P0177R2, the primary template for vector has picked up some exception specification, but the partial specialization for vector<bool> has not been so updated.

Several other changes have been made to vector in the intervening years, but these particular exception specifications have still not been updated. Note that the free-function swap in the header synopsis will automatically pick up this update once applied.

[2022-09-28; Reflector poll]

Set status to Tentatively Ready after seven votes in favour during reflector poll.

[2022-11-12 Approved at November 2022 meeting in Kona. Status changed: Voting → WP.]

Proposed resolution:

This wording is relative to N4917.

  1. Modify 23.3.12.1 [vector.bool.pspc], partial class template vector<bool, Allocator> synopsis, as indicated:

    namespace std {
      template<class Allocator>
      class vector<bool, Allocator> {
      public:
        […]
        // construct/copy/destroy
        constexpr vector() noexcept(noexcept(Allocator())) : vector(Allocator()) { }
        constexpr explicit vector(const Allocator&) noexcept;
        constexpr explicit vector(size_type n, const Allocator& = Allocator());
        constexpr vector(size_type n, const bool& value, const Allocator& = Allocator());
        template<class InputIterator>
          constexpr vector(InputIterator first, InputIterator last, const Allocator& = Allocator());
        template<container-compatible-range <bool> R>
          constexpr vector(from_range_t, R&& rg, const Allocator& = Allocator());
        constexpr vector(const vector& x);
        constexpr vector(vector&& x) noexcept;
        constexpr vector(const vector&, const type_identity_t<Allocator>&);
        constexpr vector(vector&&, const type_identity_t<Allocator>&);
        constexpr vector(initializer_list<bool>, const Allocator& = Allocator());
        constexpr ~vector();
        constexpr vector& operator=(const vector& x);
        constexpr vector& operator=(vector&& x)
          noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value ||
                   allocator_traits<Allocator>::is_always_equal::value);
        constexpr vector& operator=(initializer_list<bool>);
        template<class InputIterator>
          constexpr void assign(InputIterator first, InputIterator last);
        template<container-compatible-range <bool> R>
          constexpr void assign_range(R&& rg);
        constexpr void assign(size_type n, const bool& t);
        constexpr void assign(initializer_list<bool>);
        constexpr allocator_type get_allocator() const noexcept;
      
        […]
        constexpr iterator erase(const_iterator position);
        constexpr iterator erase(const_iterator first, const_iterator last);
        constexpr void swap(vector&)
          noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value ||
                   allocator_traits<Allocator>::is_always_equal::value);
        constexpr static void swap(reference x, reference y) noexcept;
        constexpr void flip() noexcept; // flips all bits
        constexpr void clear() noexcept;
      };
    }