根据模板整数参数选择整数类型 [英] Select an integer type based on template integer parameter
问题描述
我想创建一个类模板,该类模板接受一个无符号整数参数,并具有成员 u _
,其类型是将容纳该整数参数的最小无符号整数类型。
I would like to create a class template which takes an unsigned integer parameter and has a member u_
whose type is the smallest unsigned integer type that will hold the integer parameter.
所以:
template <uint64_t k>
class A {
??? u_;
};
对于 A< 0>
, u _
的类型应为 uint8_t
。与 A< 255>
相同。对于 A< 256>
, u _
的类型应为 uint16_t
等。
For A<0>
, u_
should be of type uint8_t
. Same for A<255>
. For A<256>
, u_
should be of type uint16_t
, etc.
您将如何实现?
推荐答案
这个元编程技巧可以达到目的:
This piece of metaprogramming trickery achieves it:
template<unsigned int Y> struct typed
{
typedef typename typed<(Y & (Y - 1)) == 0 ? Y / 2 : (Y & (Y - 1))>::type type;
};
template<> struct typed<0>
{
typedef std::uint8_t type;
};
template<> struct typed<256>
{
typedef std::uint16_t type;
};
template<> struct typed<65536>
{
typedef std::uint32_t type;
};
/* ToDo - add more specialisations as necessary*/
template<unsigned k> class A
{
public:
unsigned static const k_ = k; /*constexpr if your compiler supports it*/
typename typed<k>::type u_;
};
用法正好在问题中。
非专业模板版本采用先前的类型。 类型为<0>
会阻止静态递归。其他专业作为适当类型的定位点。
The unspecialised template version takes the previous type. typed<0>
blocks the static recursion. The other specialisations act as anchoring points for the appropriate types.
可在编译时评估的(Y&(Y-1))== 0? Y / 2:(Y&(Y-1))
通过删除 Y
的最右边的位直到达到幂次,从而减少了实例化的次数。达到2,然后除以2。 (致谢@ Jarod42)。
The compile-time evaluable (Y & (Y - 1)) == 0 ? Y / 2 : (Y & (Y - 1))
reduces the number of instantiations by removing the rightmost bit of Y
until a power of 2 is reached, and then divides by 2 subsequently to that. (Acknowledge @Jarod42).
这篇关于根据模板整数参数选择整数类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!