vector<bool>::swap(reference, reference)
is uselessSection: 23.3.12 [vector.bool] Status: New Submitter: Jonathan Wakely Opened: 2021-11-12 Last modified: 2024-08-21
Priority: 3
View other active issues in [vector.bool].
View all other issues in [vector.bool].
View all issues with New status.
Discussion:
vector<bool>
provides a static member function that can be used to swap
rvalues of type vector<bool>::reference
like so:
vector<bool> v{true, false}; vector<bool>::swap(v[0], v[1]);
This is not useful. Nobody calls swap
like that. This fails to make v[0]
swappable with
v[1]
as per 16.4.4.3 [swappable.requirements]. The similar SGI STL bit_vector
class
that vector<bool>
is partially inspired by has a "global function" with the same signature,
described as:
"Swaps the bits referred to by
x
andy
. This is a global function, not a member function. It is necessary because the ordinary version ofswap
takes arguments of typeT&
, andbit_vector::reference
is a class, not a built-in C++ reference."
For some reason this became a static member function of vector<bool>
in the C++ standard.
Previous resolution [SUPERSEDED]:
This wording is relative to N4901.
Create a new subclause [vector.bool.general] below 23.3.12 [vector.bool] and move paragraphs p1-p3 (including the class template
vector<bool, Allocator>
partial specialization synopsis) into that subclause.Add to the synopsis in [vector.bool.general] p1 (née 23.3.12 [vector.bool] p1):
[…] // bit reference class reference { friend class vector; constexpr reference() noexcept; public: constexpr reference(const reference&) = default; constexpr ~reference(); constexpr operator bool() const noexcept; constexpr reference& operator=(bool x) noexcept; constexpr reference& operator=(const reference& x) noexcept; constexpr const reference& operator=(bool x) const noexcept; constexpr void flip() noexcept; // flips the bit friend constexpr void swap(reference x, reference y) noexcept; friend constexpr void swap(reference x, bool& y) noexcept; friend constexpr void swap(bool& x, reference y) noexcept; }; […]Remove the static
swap
function from the class templatevector<bool, Allocator>
partial specialization synopsis:[…] constexpr void swap(vector&);constexpr static void swap(reference x, reference y) noexcept;constexpr void flip() noexcept; // flips all bits […]Create a new subclause [vector.bool.ref] after p3, with p4 as its first paragraph, and add after it:
22.3.12.? Class
-1-vector<bool, Allocator>::reference
[vector.bool.ref]reference
is a class that simulates the behavior of references of a single bit invector<bool>
. The conversion function returnstrue
when the bit is set, andfalse
otherwise. The assignment operators set the bit when the argument is (convertible to)true
and clear it otherwise.flip
reverses the state of the bit.constexpr void flip() noexcept;-?- Effects:
*this = !*this;
friend constexpr void swap(reference x, reference y) noexcept; friend constexpr void swap(reference x, bool& y) noexcept; friend constexpr void swap(bool& x, reference y) noexcept;-?- Effects: Exchanges the contents of
x
andy
as if by:bool b = x; x = y; y = b;Create a new subclause [vector.bool.mem] after that, containing the paragraphs describing
flip()
and thehash
specialization:22.3.12.? Class
vector<bool, Allocator>
members [vector.bool.mem]constexpr void flip() noexcept;-1- Effects: Replaces each element in the container with its complement.
constexpr static void swap(reference x, reference y) noexcept;
-6- Effects: Exchanges the contents ofx
andy
as if by:bool b = x; x = y; y = b;template<class Allocator> struct hash<vector<bool, Allocator>>;-7- The specialization is enabled (22.10.19 [unord.hash]).
Create a new subclause [depr.vector.bool.swap] after [depr.string.capacity]
D.? Deprecated
-?- The following member is declared in addition to those members specified in 23.3.12 [vector.bool]:vector<bool, Allocator>
swap [depr.vector.bool.swap]namespace std { template<class Allocator> class vector<bool, Allocator> { public: constexpr static void swap(reference x, reference y) noexcept; }; }constexpr static void swap(reference x, reference y) noexcept;-?- Effects:
swap(x, y)
.
[2022-01-22; Jonathan replaces swap(x, y)
in the Annex D
wording, following reflector discussion about lookup for swap
finding itself in that context.
]
[2022-01-30; Reflector poll]
Set priority to 3 after reflector poll.
Previous resolution [SUPERSEDED]:
This wording is relative to N4901.
Create a new subclause [vector.bool.general] below 23.3.12 [vector.bool] and move paragraphs p1-p3 (including the class template
vector<bool, Allocator>
partial specialization synopsis) into that subclause.Add to the synopsis in [vector.bool.general] p1 (née 23.3.12 [vector.bool] p1):
[…] // bit reference class reference { friend class vector; constexpr reference() noexcept; public: constexpr reference(const reference&) = default; constexpr ~reference(); constexpr operator bool() const noexcept; constexpr reference& operator=(bool x) noexcept; constexpr reference& operator=(const reference& x) noexcept; constexpr const reference& operator=(bool x) const noexcept; constexpr void flip() noexcept; // flips the bit friend constexpr void swap(reference x, reference y) noexcept; friend constexpr void swap(reference x, bool& y) noexcept; friend constexpr void swap(bool& x, reference y) noexcept; }; […]Remove the static
swap
function from the class templatevector<bool, Allocator>
partial specialization synopsis:[…] constexpr void swap(vector&);constexpr static void swap(reference x, reference y) noexcept;constexpr void flip() noexcept; // flips all bits […]Create a new subclause [vector.bool.ref] after p3, with p4 as its first paragraph, and add after it:
22.3.12.? Class
-1-vector<bool, Allocator>::reference
[vector.bool.ref]reference
is a class that simulates the behavior of references of a single bit invector<bool>
. The conversion function returnstrue
when the bit is set, andfalse
otherwise. The assignment operators set the bit when the argument is (convertible to)true
and clear it otherwise.flip
reverses the state of the bit.constexpr void flip() noexcept;-?- Effects:
*this = !*this;
friend constexpr void swap(reference x, reference y) noexcept; friend constexpr void swap(reference x, bool& y) noexcept; friend constexpr void swap(bool& x, reference y) noexcept;-?- Effects: Exchanges the contents of
x
andy
as if by:bool b = x; x = y; y = b;Create a new subclause [vector.bool.mem] after that, containing the paragraphs describing
flip()
and thehash
specialization:22.3.12.? Class
vector<bool, Allocator>
members [vector.bool.mem]constexpr void flip() noexcept;-1- Effects: Replaces each element in the container with its complement.
constexpr static void swap(reference x, reference y) noexcept;
-6- Effects: Exchanges the contents ofx
andy
as if by:bool b = x; x = y; y = b;template<class Allocator> struct hash<vector<bool, Allocator>>;-7- The specialization is enabled (22.10.19 [unord.hash]).
Create a new subclause [depr.vector.bool.swap] after [depr.string.capacity]
D.? Deprecated
-?- The following member is declared in addition to those members specified in 23.3.12 [vector.bool]:vector<bool, Allocator>
swap [depr.vector.bool.swap]namespace std { template<class Allocator> class vector<bool, Allocator> { public: constexpr static void swap(reference x, reference y) noexcept; }; }constexpr static void swap(reference x, reference y) noexcept;-?- Effects: Exchanges the contents of
x
andy
as if by:bool b = x; x = y; y = b;
[2024-08-21; Jonathan provides improved wording]
Rebase on the current draft, change "exchanges the contents" to "exchanges the denoted values", and don't split the subclause into new subclauses.
Proposed resolution:
This wording is relative to N4988.
Add to the synopsis in 23.3.12.1 [vector.bool.pspc] p1:
[…] // bit reference class reference { friend class vector; constexpr reference() noexcept; public: constexpr reference(const reference&) = default; constexpr ~reference(); constexpr operator bool() const noexcept; constexpr reference& operator=(bool x) noexcept; constexpr reference& operator=(const reference& x) noexcept; constexpr const reference& operator=(bool x) const noexcept; constexpr void flip() noexcept; // flips the bit friend constexpr void swap(reference x, reference y) noexcept; friend constexpr void swap(reference x, bool& y) noexcept; friend constexpr void swap(bool& x, reference y) noexcept; }; […]
Remove the static swap
function from the same synopsis:
[…] constexpr void swap(vector&) noexcept(allocator_traits<Allocator>::propagate_on_container_swap::value || allocator_traits<Allocator>::is_always_equal::value);static constexpr void swap(reference x, reference y) noexcept;constexpr void flip() noexcept; // flips all bits constexpr void clear() noexcept; […]
Modify the paragraphs below the synopsis as shown:
-4-
reference
is a class that simulates the behavior of references of a single bit invector<bool>
. The conversion function returnstrue
when the bit is set, andfalse
otherwise. The assignment operators set the bit when the argumentis (convertible to)converts totrue
and clear it otherwise.flip
reverses the state of the bit.constexpr void reference::flip() noexcept;-?- Effects:
*this = !*this;
constexpr void swap(reference x, reference y) noexcept; constexpr void swap(reference x, bool& y) noexcept; constexpr void swap(bool& x, reference y) noexcept;-?- Effects: Exchanges the values denoted by
x
andy
as if by:bool b = x; x = y; y = b;constexpr void flip() noexcept;-1- Effects: Replaces each element in the container with its complement.
constexpr static void swap(reference x, reference y) noexcept;
-6- Effects: Exchanges the contents ofx
andy
as if by:bool b = x; x = y; y = b;template<class Allocator> struct hash<vector<bool, Allocator>>;-7- The specialization is enabled (22.10.19 [unord.hash]).
Create a new subclause [depr.vector.bool.swap] after D.19 [depr.format]
D.? Deprecated
-?- The following member is declared in addition to those members specified in 23.3.12 [vector.bool]:vector<bool, Allocator>
swap [depr.vector.bool.swap]namespace std { template<class Allocator> class vector<bool, Allocator> { public: static constexpr void swap(reference x, reference y) noexcept; }; }static constexpr void swap(reference x, reference y) noexcept;-?- Effects: Exchanges the values denoted by
x
andy
as if by:bool b = x; x = y; y = b;