我想要一个类型函数,它接受一个类型T并返回满足sizeof(I) >= sizeof(T)
的最小整数类型。
有关如何处理此问题的任何想法,见解或评论?可以使用C ++ 11,欢迎使用C ++ 14。
对于好奇:
我正在研究编程元素。
我有一个函数,它从一个组(如int)映射到它自己。令x在函数的域中,并且通过将f应用于x多次来获得y。我想知道在得到y之前我有多少次将函数应用于x。该值称为距离,是一些整数。如果以k位指定组类型,则不同值的总数为pow(2,k)
。然后,元素之间可能跳转的总数为pow(2,k) - 1
。因此,与组类型具有相同大小的整数类型足以容纳此距离函数可能返回的所有可能距离。
答案 0 :(得分:6)
这应该这样做:
template<typename T>
struct identity {
typedef T type;
};
template<typename T, typename Head, typename... Tail>
struct best_type {
typedef typename std::conditional<
sizeof(Head) >= sizeof(T),
identity<Head>,
best_type<T, Tail...>
>::type::type type;
};
template<typename T>
struct type_to_integral {
typedef typename best_type<T, uint8_t, uint16_t, uint32_t, uint64_t, uint_least64_t>::type type;
};
现场演示here。
答案 1 :(得分:0)
这是我根据mfontanini的回答和Yakk的评论使用的例子。
//In metaprogramming library header
template<bool B, typename T, typename F>
using Conditional = typename std::conditional<B,T,F>::type;
//In application header
template<typename T, typename Head, typename... Tail>
struct big_enough{
using type =
Conditional<sizeof(T) <= sizeof(Head),
Head,
typename big_enough<T, Tail...>::type
>;
};
template<typename T, typename Head>
struct big_enough<T, Head>{
using type = Head;
};
template<typename T>
struct containing_integer{
using type =
typename big_enough<T, uint8_t, uint16_t, uint32_t, uint64_t, uint_least64_t, double>::type;
static_assert(std::is_integral<type>::value, "Type is too large");
};
注意我在类型列表的末尾添加了double
,并将identity
压缩为big_enough
的特化。如果我决定在标题中包含标识,那么我可以更改
template<typename T, typename Head>
struct big_enough<T, Head>{
using type = Head;
};
到
template<typename T, typename Head>
struct big_enough<T, Head> :
identity<Head>
{};
因为后者使用SFINAE。
现在尝试找到一个更大的整数类型,然后'int64_t [2]'返回错误:
Transformation.cpp: In instantiation of 'struct containing_integer<long long int [2]>':
Transformation.cpp:86:54: required from here
Transformation.cpp:33:3: error: static assertion failed: Type is too large
static_assert(std::is_integral<type>::value, "Type is too large");
这很容易阅读。