Created on 2024-12-21.00:00:00 last changed 3 months ago
Proposed resolution:
This wording is relative to N5001.
Modify [template.bitset.general] as indicated:
namespace std { template<size_t N> class bitset { public: // bit reference class reference { public: constexpr reference(const reference&) = default; constexpr ~reference(); constexpr reference& operator=(bool x) noexcept; // for b[i] = x; constexpr reference& operator=(const reference&) noexcept; // for b[i] = b[j]; constexpr const reference& operator=(bool x) const noexcept; constexpr bool operator~() const noexcept; // flips the bit constexpr operator bool() const noexcept; // for x = b[i]; constexpr reference& flip() noexcept; // for b[i].flip(); }; […] }; […] }
[ 2025-02-07; Jonathan provides improved wording ]
Moved `swap` changes to LWG 3638.
[ 2025-02-07; Reflector poll ]
Set priority to 3 after reflector poll.
"Just const-quality the existing assignment operators."
"Would need to change the return type (breaking) or use `const_cast` (weird)."
"And it would be needlessly inconsistent with vector<bool>::reference
."
"The `swap` part belongs in LWG 3638."
This wording is relative to N5001.
Modify [template.bitset.general] as indicated:
namespace std { template<size_t N> class bitset { public: // bit reference class reference { public: constexpr reference(const reference&) = default; constexpr ~reference(); constexpr reference& operator=(bool x) noexcept; // for b[i] = x; constexpr reference& operator=(const reference&) noexcept; // for b[i] = b[j]; constexpr const reference& operator=(bool x) const noexcept; constexpr bool operator~() const noexcept; // flips the bit constexpr operator bool() const noexcept; // for x = b[i]; constexpr reference& flip() noexcept; // for b[i].flip(); 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; }; […] }; […] }
LWG 3638, which proposes changes to vector<bool>::reference, is related. Should vector<bool>::reference and bitset<N>::reference behave differently in any respect? I think there's no good reason for them to behave differently, and good technical incentives to permit them to behave the same. We already have implementation divergence: libc++ makes `bitset::reference` const-assignable, whereas libstdc++ and MS STL do not. This means that libc++'s `bitset::reference` successfully avoids false positives from Arthur's proposed -Wassign-to-class-rvalue diagnostic, while libstdc++'s does not (See Godbolt).
The proposed resolution applies P2321's approach. We can't just insert `const` into the existing spec, because ABI. But also, since our goal is consistency with the post-P2321 vector<bool>::reference, we should do the same thing here as P2321, not invent anything novel. Open questions related to the current P/R:LWG 3638 proposes to add these three `swap` overloads to vector<bool>::reference. Should we also, consistently, add them to `bitset::reference`? I think we should.
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;
Both vector<bool>::reference and `bitset::reference` right now are specified with
constexpr reference(const reference&) = default;
which is meaningless because we don't know the data members of `reference`. So this isn't actually specifying that the constructor is trivial, let alone that it's `noexcept`. I think we should re-specify both types' copy constructors as simply `constexpr` and `noexcept`; and then if we want them to be trivial, we should say so in English prose.
History | |||
---|---|---|---|
Date | User | Action | Args |
2025-02-07 22:25:24 | admin | set | messages: + msg14616 |
2025-02-07 22:17:52 | admin | set | messages: + msg14609 |
2024-12-22 11:35:12 | admin | set | messages: + msg14531 |
2024-12-21 00:00:00 | admin | create |