This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.

4543. Incorrect cast between simd::vec and simd::mask via conversion to and from impl-defined vector types

Section: 29.10.7 [simd.class], 29.10.9 [simd.mask.class] Status: New Submitter: Matthias Kretz Opened: 2026-03-16 Last modified: 2026-03-18

Priority: Not Prioritized

View all issues with New status.

Discussion:

Consider:

simd::vec<int> x = 1;
simd::vec<short> a = x; // ill-formed & concise error 👍
auto b = static_cast<simd::vec<short>>(x); // might compile or fail with pages of errors

simd::mask<complex<float>> k = true;
auto c = static_cast<simd::mask<float>>(k); // might compile or fail with pages of errors

Why can b and c sometimes work? It depends on the implementation, whether and how it implements the "recommended practice" of implicit conversion to and from implementation-defined non-standard vector types.

E.g. vec<int> could be convertible to __m256i and __m256i is then convertible to vec<short>. Likewise, mask<complex<float>> could be implemented as a mask<float> internally, making it convertible to __vector(8) int, the same type that mask<float> uses.

If the implicit conversion constructor is implemented as a constrained template, there's no problem. However, a non-template such as e.g.

basic_mask(__m256i)

enables the conversion sequence from another basic_vec or basic_mask.

Given an enabled basic_vec specialization V the following must always hold:

constructible_from<V, simd::rebind_t<int, V>>
constructible_from<V, simd::rebind_t<float, V>>
!constructible_from<V, simd::resize_t<V::size() + 1, V>>
!constructible_from<V, simd::resize_t<V::size() + 1, typename V::mask_type>>
!constructible_from<typename V::mask_type, V>

Given an enabled basic_mask specialization M the following must always hold:

std::constructible_from<M, simd::rebind_t<int, M>>
std::constructible_from<M, simd::rebind_t<float, M>>
!std::constructible_from<M, simd::resize_t<M::size() + 1, M>>

There are two possible solutions:

  1. delete all unwanted conversions explicitly or

  2. require the "recommended practice" conversion constructors to use a constrained template.

I strongly favor the first solution because it not only removes the incorrect conversions but also reduces the error message to something understandable, additionally allowing a message from the developer via = delete("wrong!").

Proposed resolution: Adopt P4042R0

Proposed resolution: