根据此处的答案,我制作了一个现代的“伪演员”功能,以方便应用。
C99 版本
(虽然大多数编译器都支持它,但理论上在某些情况下可能是未定义的行为)
template <typename T, typename U>
inline T pseudo_cast(const U &x)
{
static_assert(std::is_trivially_copyable<T>::value && std::is_trivially_copyable<U>::value, "pseudo_cast can't handle types which are not trivially copyable");
union { U from; T to; } __x = {x};
return __x.to;
}
通用版本
(基于接受的答案)
大小相同的演员表类型:
#include <cstring>
template <typename T, typename U>
inline T pseudo_cast(const U &x)
{
static_assert(std::is_trivially_copyable<T>::value && std::is_trivially_copyable<U>::value, "pseudo_cast can't handle types which are not trivially copyable");
static_assert(sizeof(T) == sizeof(U), "pseudo_cast can't handle types with different size");
T to;
std::memcpy(&to, &x, sizeof(T));
return to;
}
任何尺寸的铸造类型:
#include <cstring>
template <typename T, typename U>
inline T pseudo_cast(const U &x)
{
static_assert(std::is_trivially_copyable<T>::value && std::is_trivially_copyable<U>::value, "pseudo_cast can't handle types which are not trivially copyable");
T to = T(0);
std::memcpy(&to, &x, (sizeof(T) < sizeof(U)) ? sizeof(T) : sizeof(U));
return to;
}
像这样使用它:
float f = 3.14f;
uint32_t u = pseudo_cast<uint32_t>(f);
C++20 更新
C++20constexpr
std::bit_cast
在标头<bit>
中引入了对于具有相同大小的类型在功能上等效的功能。尽管如此,如果您想自己实现此功能(假设constexpr
不是必需的),或者如果您想支持不同大小的类型,上述版本仍然有用。