1. Motivation
There are two types of casting in 
1.1. Type casting
Type casting in 
template < typename T , typename ABI > auto incrementAsFloat1 ( const basic_simd < T , ABI >& x ) { // Use constructor. return rebind_simd_t < float , basic_simd < T , ABI >> ( x ) + 1.0f ; } template < typename T , typename ABI > auto incrementAsFloat ( const basic_simd < T , ABI >& x ) { // Use static_cast using OUT = simd < float , basic_simd < T , ABI >:: size > ; return static_cast < OUT > ( x ) + 1.0f ; } 
Note that there are other ways to write these, perhaps using extra aliases or intermediate temporary variables to improve readability. However, it is much cleaner to be able to write them like this instead:
template < typename T , typename ABI > auto incrementAsFloat ( const basic_simd < T , ABI >& x ) { return simd_cast < float > ( x ) + 1.0f ; } 
The 
Of course there are times when the type-conversion may also require a change in
ABI (e.g., to create a new element type with an alternative target type) in
which 
Another good reason to use 
// simd-generic function auto incrementAsFloat ( auto x ) { return simd_cast < float > ( x ) + 1.0f ; } // Call with scalar: auto w1 = incrementAsFloat ( 23.f ); // Call with simd: auto w2 = incrementAsFloat ( simd < int > ( ptr )); 
Finally, it is worth noting that while it would be straight-forward for
programmers to define 
1.2. Bit-casting
The second type of casting operation is bit-casting, where the underlying bit
pattern is interpreted as though it were a different 
The existing 
// Do something to a complex simd value ([[R2663R5]]). template < typename T , typename ABI > auto fn ( const basic_simd < std :: complex < T > , ABI >& x ) { // Setup a type to represent the raw floating point elements in the // complex simd types. This doubles the number of elements in the simd. constexpr int numNativeCmplxElements = simd < std :: complex < float >>:: size ; using AsFloat = simd < float , numNativeCmplxElements * 2 > ; // Do the bit-cast conversion to obtain the raw float elements. auto asT = std :: bit_cast < AsFloat > ( x ); auto result = ...; // e.g., call an Intel intrinsic like _mm512_fmsubadd_ps // Convert back to its original complex form. return std :: bit_cast < basic_simd < std :: complex < T > , ABI >> ( result ); } 
This example shows the verbose mechanics of making that conversion. The correct
type needs to be created by calculating the appropriate number of new elements
for the bit-cast element type, and then creating a suitable type using those
elements, before 
template < typename T , typename ABI > auto fn ( const basic_simd < std :: complex < T > , ABI >& x ) { auto asT = simd_bit_cast < T > ( x ); auto result = ...; // e.g., call an Intel intrinsic like _mm512_fmsubadd_ps return simd_bit_cast < std :: complex < T >> ( result ); } 
The 
Like 
Note that no functions will be provided to bit-cast 
2. Implementation experience
In Intel’s implementation of 
The implementation of Intel’s 
Intel uses 
3. Wording
3.1. Add [simd.casts] to the synopsis
Add the following to the [simd.syn] section:
// [simd.copy], basic_simd cast functions template < typename To , typename From > constexpr To simd_cast ( const From & x ); template < typename To , typename From , typename Abi > constexpr rebind_simd_t < To , basic_simd < From , Abi >> simd_cast ( & x ); template < typename To , typename From > constexpr To simd_bit_cast ( const From & x ); template < typename To , typename From , typename Abi > constexpr simd < To , ( basic_simd < From , Abi >:: size * sizeof ( From )) / sizeof ( To ) > simd_bit_cast ( const basic_simd < From , Abi >& x ); 
3.2. Add new simd cast section [simd.casts]
�
casts [simd.casts]basic_simd 1 ) template < typename To , typename From > constexpr To simd_cast ( const From & x ); 2 ) template < typename To , typename From , typename Abi > constexpr rebind_simd_t < To , basic_simd < From , Abi >> simd_cast ( & x ); Returns:
For the first overload, equivalent to returning
.static_cast < To > ( x ) 
For the second overload, equivalent to returning
.static_cast < rebind_simd_t < To , basic_simd < From , Abi >>> ( x ) 1 ) template < typename To , typename From > constexpr To simd_bit_cast ( const From & x ); 2 ) template < typename To , typename From , typename Abi > constexpr simd < To , ( basic_simd < From , Abi >:: size * sizeof ( From )) / sizeof ( To ) > simd_bit_cast ( const basic_simd < From , Abi >& x ); Returns:
For the first overload, equivalent to returning
.std :: bit_cast < To > ( x ) 
For the second overload, equivalent to returning
.std :: bit_cast < simd < To , ( basic_simd < From , Abi >:: size * sizeof ( From )) / sizeof ( To ) >> ( x )