Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
200 views
in Technique[技术] by (71.8m points)

c++ - Select an integer type based on template integer parameter

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.

So:

template <uint64_t k>
class A {
  ??? u_;
};

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.

How would you implement this?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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_;
};

The usage is exactly in the question.

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.

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).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...