According to the reinterpret_cast page on cppreference.com, there are 11 conversions that
can be done with
reinterpret_cast, except when such conversions would cast away constness or volatility.
So, my question is: is it possible to write a constexpr function like
template <typename T1, typename T2>
constexpr bool is_reinterpret_cast_safe() {
// ...
}
that checks whether the conversion if allowed or not, based on those 11 points? Since compilers like GCC and Clang are able to check if the code breaks the strict aliasing rule, compiling with -fstrict-aliasing -Wstrict-aliasing, I think is should be possible somehow.
I know C++20 introduces std::bit_cast, but it is still not supported by any compiler. It could be useful to select between two casting functions at compile time
template <typename T1, typename T2>
T1 f_reinterpret_cast(T2 d) {
static_assert(sizeof(T1) == sizeof(T2));
return *reinterpret_cast<T1*>(&d); // could be undefined behavior;
}
template <typename T1, typename T2>
T1 f_memcpy(T2 d) {
static_assert(sizeof(T1) == sizeof(T2));
T1 n;
std::memcpy(&n, &d, sizeof(T2)); // OK
return n;
}
with SFINAE or if constexpr:
template <typename T1, typename T2>
T1 conv(T2 d) {
if constexpr (is_reinterpret_cast_safe<T1, T2>())
return conv_reinterpret_cast<T1, T2>(d);
else
return conv_memcpy<T1, T2>(d);
}
You may find the code on https://godbolt.org/z/Ex6GnP.