C++ 断言该类型是无符号整数或具有最大大小的枚举类型
我尝试编写以下代码,以静态断言变量类型是大小小于或等于四个字节的无符号整数 我从以下几点开始:C++ 断言该类型是无符号整数或具有最大大小的枚举类型,c++,c++11,templates,C++,C++11,Templates,我尝试编写以下代码,以静态断言变量类型是大小小于或等于四个字节的无符号整数 我从以下几点开始: 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(
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)>;
模板
使用is_uint_le32_t=std::integral_常量<
布尔,
std::is_integral::value
&&std::is_unsigned::value
&&sizeof(T);
这样我就可以编写静态断言(is\u uint\u le32\u t)
但是,当
T
是一个枚举类型,其基础类型满足是
并且我不知道如何做时,我希望这个别名模板也可以求值为true
。我们可以使用std::conditional
获取枚举类型的基础类型,或者不使用任何其他类型:
#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>>;
#包括
名称空间std_compat{
#如果uu cplusplus>=202002L
使用::std::type_标识;
#否则
模板
结构类型标识{
使用类型=T;
};
#恩迪夫
}
模板
使用基础\u或\u id\u t=typename std::conditional<
std::is_enum::value,std::底层_类型,std_compat::type_标识
>::类型::类型;
模板
使用is_uint_le32_no_enum=std::integral_常量<
布尔,
std::is_integral::value
&&std::is_unsigned::value
&&sizeof(T);
模板
使用is_uint_le32_t=is_uint_le32_no_enum;
我们可以使用std::conditional
获取枚举类型的基础类型,或者不使用任何其他类型:
#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>>;
#包括
名称空间std_compat{
#如果uu cplusplus>=202002L
使用::std::type_标识;
#否则
模板
结构类型标识{
使用类型=T;
};
#恩迪夫
}
模板
使用基础\u或\u id\u t=typename std::conditional<
std::is_enum::value,std::底层_类型,std_compat::type_标识
>::类型::类型;
模板
使用is_uint_le32_no_enum=std::integral_常量<
布尔,
std::is_integral::value
&&std::is_unsigned::value
&&sizeof(T);
模板
使用is_uint_le32_t=is_uint_le32_no_enum;
对于任何关心此事的人,我刚刚提出了一个可能更简单的解决方案:
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>(); }
模板
constexpr typename std::enable_if::type
是(u uint)le32(u t)
{return std::is_unsigned::value&&sizeof(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>(); }
模板
constexpr typename std::enable_if::type
是(u uint)le32(u t)
{return std::is_unsigned::value&&sizeof(T)制作另一个模板以测试类型或基础类型是否满足条件的明显解决方案有什么问题?您尝试了哪些不起作用的方法?制作另一个模板以测试类型或基础类型是否满足条件的明显解决方案有什么问题?您尝试过哪些不起作用的方法?在这里使用类型一致性
而不是简单地使用t
,有什么意义呢?@super我们不能在条件
中包含基础类型::类型
,因为这对于非枚举是格式错误的,条件
无法避免该错误。因此最终的::type
需要在条件之外,但是在非枚举的情况下,我们需要::键入以“展开”某些内容以返回T
(另外,现在我认为部分专门化解决方案会更简单…)啊,对了。我刚刚意识到你有双重::type::type
外部条件用于此目的。这现在是有意义的了。@aschepler:这正是我一直在努力解决的问题,回答得很好。在这里使用类型一致性
而不是简单地使用T
,有什么意义呢?@super我们不能有底层type::type
在条件
内,因为这对于非枚举是格式不正确的,并且条件
不能避免该错误。因此最后的::type
需要在条件
外,但是在非枚举的情况下,我们需要::type
来“展开”要返回到t
的内容。(还有,现在我想部分专门化解决方案会更简单…)啊,对了。我刚刚意识到你有双重::type::type
外部条件
。这现在是有意义的。@aschepler:这正是我一直在努力解决的问题,回答得很好。