断言该类型是无符号整数或具有最大大小的枚举类型



我正试图写以下内容来静态断言变量类型是大小小于或等于四个字节的无符号整数。

我从以下内容开始:

template<typename T>
using is_uint_le32_t = std::integral_constant<
bool,
std::is_integral<T>::value
&& std::is_unsigned<T>::value
&& sizeof(T) <= sizeof(uint32_t)>;

这样我就可以写static_assert(is_uint_le32_t<T>)了。

然而,当T是一个枚举类型,其底层类型满足is_uint_le32_t时,我希望这个别名模板也能评估为true,我不知道如何做到这一点。

我们可以使用std::condtional来获取枚举类型的底层类型,也可以不使用任何其他类型:

#include <type_traits>
namespace std_compat {
#if __cplusplus >= 202002L
using ::std::type_identity;
#else
template <typename T>
struct type_identity {
using type = T;
};
#endif
}
template <typename T>
using underlying_or_id_t = typename std::conditional<
std::is_enum<T>::value, std::underlying_type<T>, std_compat::type_identity<T>
>::type::type;
template<typename T>
using is_uint_le32_no_enum = std::integral_constant<
bool,
std::is_integral<T>::value
&& std::is_unsigned<T>::value
&& sizeof(T) <= sizeof(uint32_t)>;
template<typename T>
using is_uint_le32_t = is_uint_le32_no_enum<underlying_or_id_t<T>>;

对于任何可能关心的人,我刚刚提出了一个可能更简单的解决方案:

template<typename T>
constexpr typename std::enable_if<std::is_integral<T>::value, bool>::type
is_uint_le32_t()
{ return std::is_unsigned<T>::value && sizeof(T) <= sizeof(uint32_t); }
template<typename T>
constexpr typename std::enable_if<std::is_enum<T>::value, bool>::type
is_uint_le32_t()
{ return is_uint_le32_t<typename std::underlying_type<T>::type>(); }

像这样使用:

static_assert(is_uint_le32_t<T>());

最新更新