根据cppreference.com上的
reinterpret_cast
页面,除了会转换掉constness或volatility之外,可以使用11种转换方式进行reinterpret_cast
。那么,我的问题是:是否可能编写像这样的constexpr函数?template <typename T1, typename T2>
constexpr bool is_reinterpret_cast_safe() {
// ...
}
根据这11个点检查转换是否允许?由于编译器(如GCC和Clang)能够检查代码是否违反严格别名规则,因此使用-fstrict-aliasing -Wstrict-aliasing
编译,我认为应该可以以某种方式实现。
我知道C++20引入了std::bit_cast
, 但目前还没有任何编译器支持。在编译时选择两个转换函数可能会很有用。
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;
}
使用SFINAE或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);
}
您可以在https://godbolt.org/z/Ex6GnP上找到代码。
if ((std::is_integral<T1> || std::is_enum<T1> || std::is_pointer<T1> || std::is_member_object_pointer<T1>) && std::is_same<T1, T2>) return true;
- KamilCukstd::memcpy
函数? - Acorn