Title
Incorrect cast between `simd::vec` and `simd::mask` via conversion to and from impl-defined vector types
Status
new
Section
[simd.class][simd.mask.class]
Submitter
Matthias Kretz

Created on 2026-03-16.00:00:00 last changed 2 weeks ago

Messages

Date: 2026-03-18.16:15:34

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

History
Date User Action Args
2026-03-16 00:00:00admincreate