This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of Tentatively Ready status.
simd::basic_mask(bool) overload needs to be more constrained
Section: 29.10.9.2 [simd.mask.ctor] Status: Tentatively Ready Submitter: Matthias Kretz Opened: 2025-09-24 Last modified: 2025-10-27
Priority: Not Prioritized
View all issues with Tentatively Ready status.
Discussion:
29.10.9.2 [simd.mask.ctor] defines the overloads basic_mask(bool) and
basic_mask(unsigned_integral auto). This leads to the following pitfall:
auto g0() {
unsigned short k = 0xf;
return simd::mask<float, 8>(k); // mov eax, 15
}
auto g1() {
unsigned short k = 0xf;
return simd::mask<float, 8>(k >> 1); // mov eax, -1 ⚠️
}
auto g2() {
unsigned int k = 0xf;
return simd::mask<float, 8>(k >> 1); // mov eax, 7
}
In g1, k is promoted to int, shifted and then passed to
the mask constructor. Instead of failing, int(0x7) is
converted to bool and the mask thus initialized to all true.
simd::mask<float>(true_type());
unsigned_integral<bool> is true =>
same_as<bool> auto instead of 'bool' makes
the overload set ambiguous
float is convertible to bool, thus
simd::mask<float>(1.f) continues to compile
Previous resolution [SUPERSEDED]:
This wording is relative to N5014.
Modify 29.10.9.1 [simd.mask.overview],
class template basic_masksynopsis, as indicated:namespace std::simd { template<size_t Bytes, class Abi> class basic_mask { public: […] constexpr basic_mask() noexcept = default; // 29.10.9.2 [simd.mask.ctor], basic_mask constructors constexpr explicit basic_mask(value_type) noexcept; template<size_t UBytes, class UAbi> constexpr explicit basic_mask(const basic_mask<UBytes, UAbi>&) noexcept; template<class G> constexpr explicit basic_mask(G&& gen) noexcept; constexpr basic_mask(const bitset<size()>& b) noexcept; constexpr explicit basic_mask(unsigned_integral auto val) noexcept; basic_mask(signed_integral auto) = delete; […] }; }
[2025-10-06; Matthias Kretz improves wording after reflector discussion]
[2025-10-23; Reflector poll.]
Set status to Tentatively Ready after seven votes in favour during reflector poll.
Proposed resolution:
This wording is relative to N5014.
Modify 29.10.9.1 [simd.mask.overview], class template basic_mask synopsis, as indicated:
namespace std::simd {
template<size_t Bytes, class Abi> class basic_mask {
public:
[…]
constexpr basic_mask() noexcept = default;
// 29.10.9.2 [simd.mask.ctor], basic_mask constructors
constexpr explicit basic_mask(same_as<value_type> auto) noexcept;
template<size_t UBytes, class UAbi>
constexpr explicit basic_mask(const basic_mask<UBytes, UAbi>&) noexcept;
template<class G>
constexpr explicit basic_mask(G&& gen) noexcept;
template<same_as<bitset<size()>> T>
constexpr basic_mask(const Tbitset<size()>& b) noexcept;
template<unsigned_integral T> requires (!same_as<T, value_type>)
constexpr explicit basic_mask(Tunsigned_integral auto val) noexcept;
[…]
};
}
Modify 29.10.9.2 [simd.mask.ctor] as indicated:
constexpr explicit basic_mask(same_as<value_type> auto x) noexcept;[…]-1- Effects: Initializes each element with
x.template<same_as<bitset<size()>> T> constexpr basic_mask(const Tbitset<size()>& b) noexcept;-7- Effects: Initializes the
ith element withb[i]for alliin the range[0, size()).template<unsigned_integral T> requires (!same_as<T, value_type>) constexpr explicit basic_mask(Tunsigned_integral autoval) noexcept;-8- Effects: Initializes the first
Melements to the corresponding bit values inval, […]