如果您希望某些东西在每种整数类型上都能正常工作,您可以将其嵌入到通过几个步骤构建的特征中。我们首先将整数类型映射到它们的位大小:
#define CREATE_SIGNED_META_OBJ(x) template <>\
struct signed_integer_type<x> {\
typedef int##x##_t type;\
};
#define CREATE_UNSIGNED_META_OBJ(x) template <>\
struct unsigned_integer_type<x> {\
typedef uint##x##_t type;\
};
template <std::size_t length>
struct signed_integer_type;
template <std::size_t len>
struct unsigned_integer_type;
CREATE_SIGNED_META_OBJ(8)
CREATE_SIGNED_META_OBJ(16)
CREATE_SIGNED_META_OBJ(32)
CREATE_SIGNED_META_OBJ(64)
CREATE_UNSIGNED_META_OBJ(8)
CREATE_UNSIGNED_META_OBJ(16)
CREATE_UNSIGNED_META_OBJ(32)
CREATE_UNSIGNED_META_OBJ(64)
然后,可以构建特征本身。我们想将我们的二分法应用于断言std::numeric_limits<Int>::min() == 0...
template <typename Int, bool>
struct get_smallest_for_max_plus_one;
template <typename Int>
struct get_smallest_for_max_plus_one<Int, true> {
typedef typename signed_integer_type<2*sizeof(Int)*8>::type type;
};
template <typename Int>
struct get_smallest_for_max_plus_one<Int, false> {
typedef typename unsigned_integer_type<sizeof(Int)*8>::type type;
};
template <typename Int>
using get_fittest_int_type = get_smallest_for_max_plus_one<Int, std::numeric_limits<Int>::min() == 0>;
现在我们可以直接将get_fittest_int_type 与任何整数一起使用...运行示例可以在Coliru 上找到。
不过,为了保持一致性,我想您想保留 signed 或 unsigned 属性...如果是这种情况,您可以将 get_smallest_for_max_plus_one 的特化替换为以下内容:
// Unsigned type, we want to get the smallest unsigned type that can hold max + 1
template <typename Int>
struct get_smallest_for_max_plus_one<Int, true> {
typedef typename unsigned_integer_type<2*sizeof(Int)*8>::type type;
};
// Signed type, we want the smallest signed type that can hold max + 1
template <typename Int>
struct get_smallest_for_max_plus_one<Int, false> {
typedef typename signed_integer_type<2*sizeof(Int)*8>::type type;
};