C++ 如何在编译时计算出可以表示数字的最小整数类型

C++ 如何在编译时计算出可以表示数字的最小整数类型,c++,templates,c++11,typetraits,C++,Templates,C++11,Typetraits,我需要在编译时找出能够表示特定数字的最小无符号整数类型。像这样的 ////////////////////////////////////////////////////////////////////////// template<size_t Bits> struct uint_least{}; template<> struct uint_least<8>{ typedef std::uint8_t type; }; template<>

我需要在编译时找出能够表示特定数字的最小无符号整数类型。像这样的

//////////////////////////////////////////////////////////////////////////
template<size_t Bits>
struct uint_least{};

template<>
struct uint_least<8>{ typedef std::uint8_t type; };

template<>
struct uint_least<16>{ typedef std::uint16_t type; };

//////////////////////////////////////////////////////////////////////////
template<size_t max>
struct uint_least_bits
{
    static const size_t value = 14; // just a placeholder
};

//////////////////////////////////////////////////////////////////////////
template<size_t max>
class A
{
    typedef typename uint_least<uint_least_bits<max>::value>::type underlying_type;

    underlying_type m_X;
};
//////////////////////////////////////////////////////////////////////////
模板
结构uint_least{};
模板
结构uint_至少{typedef std::uint8_t type;};
模板
结构uint_至少{typedef std::uint16_t type;};
//////////////////////////////////////////////////////////////////////////
模板
结构单元\u最少\u位
{
静态常量size\u t value=14;//只是一个占位符
};
//////////////////////////////////////////////////////////////////////////
模板
甲级
{
typedef typename uint_least::type-undernative_-type;
基本的m_类型m_X;
};
uint_least
意味着为您提供最小的无符号整数类型,该类型至少为
大,并且它应该适用于最多64位的任何值(不仅是8、16、32、64,还包括1、4、13等)

uint\u least\u bits
旨在为您提供表示
max
所需的最小位数

  • 如何实现
    uint\u(至少)
  • 如何实现
    uint\u最少\u位
  • bits
    min
    max
    应该是什么类型?如果答案是模板类型,如何防止无效输入

这些特征的确切结构并不重要。请随意放弃我提供的东西。我只需要提供一个数字,然后返回可以容纳它的最小无符号整数类型。

如果您有
constepr
,这将起作用:

#include <climits>
#include <cstdint>
#include <cstddef>

inline
constexpr
unsigned
clz(unsigned x)
{
    return x == 0 ? sizeof(x)*CHAR_BIT : x & 0x80000000 ? 0 : 1 + clz(x << 1);
}

inline
constexpr
unsigned
clp2(unsigned x)
{
    return x == 0 ? 0 : 1 << (sizeof(x)*CHAR_BIT - clz(x-1));
}

inline
constexpr
unsigned
at_least8(unsigned x)
{
    return x < 8 ? 8 : x;
}

template<size_t Bits>
struct uint_least{};

template<>
struct uint_least<8>{ typedef std::uint8_t type; };

template<>
struct uint_least<16>{ typedef std::uint16_t type; };

template<>
struct uint_least<32>{ typedef std::uint32_t type; };

template<>
struct uint_least<64>{ typedef std::uint64_t type; };

template<size_t max>
struct uint_least_bits
{
    static const size_t value = clp2(max);
};

template<size_t max>
class A
{
    typedef typename uint_least<at_least8(uint_least_bits<max>::value)>::type underlying_type;

    underlying_type m_X;
};

int main()
{
    A<3> a;
}
#包括
#包括
#包括
内联
常量表达式
未签名
clz(无符号x)
{

return x==0?sizeof(x)*CHAR_BIT:x&0x8000000?0:1+clz(x我昨天刚刚做了这个,真是巧合。我把它放在这里,尽管它并不完全是您需要的(它修复了最好的整数类型):

#包括
#包括
模板
结构最佳类型{
typedef typename std::conditional<
(一)类型;
};
然后,你会这样使用它:

#include <type_traits>
#include <iostream>
#include <stdint.h>

template<size_t i>
struct best_type {
    typedef typename std::conditional<
        (i <= 8),
        uint8_t,
        typename std::conditional<
            (i <= 16),
            uint16_t,
            typename std::conditional<
                (i <= 32),
                uint32_t,
                uint64_t
            >::type
        >::type
    >::type type;
};   

int main() {
    std::cout << sizeof(best_type<2>::type) << std::endl;
    std::cout << sizeof(best_type<8>::type) << std::endl;
    std::cout << sizeof(best_type<15>::type) << std::endl;
    std::cout << sizeof(best_type<17>::type) << std::endl;
}
#包括
#包括
#包括
模板
结构最佳类型{
typedef typename std::conditional<
(一)类型;
};   
int main(){

std::你能不能对整型常量使用
decltype
int\u least\u bits::value
应该是1还是9?@GManNickG好问题。我会说9,但请随意不同意并告诉我why@Dave:因为我可以在一位中编码两个整数值,零表示第一位,一表示第二位。基本上,是这样的:“我可以使用什么类型来编码此范围内的值”或“我可以使用什么类型来直接分配此范围内的文字值”?表示“在您的问题中,是什么导致了这种歧义。@KerrekSB:
decltype
不会为足够小的值提供最小的类型以提升到
int
。例如,
decltype(1)
int
,不是
char
类型中的一种。+1但我应该因为在OP最不期望的时候使用
constepr
而获得学分。:-)如果我错了,请告诉我,但我认为在定义
constexpr
函数时精确
inline
是没有用的。如果使用非constexpr参数调用,constexpr函数仍然可以在运行时运行。根据C++11标准,第7.1.5节:
constexpr函数和constexpr构造函数是隐式内联的
。好的,还没有这与当前的问题有关。至少我有一个问题的答案。很抱歉给你添麻烦。
#include <type_traits>
#include <iostream>
#include <stdint.h>

template<size_t i>
struct best_type {
    typedef typename std::conditional<
        (i <= 8),
        uint8_t,
        typename std::conditional<
            (i <= 16),
            uint16_t,
            typename std::conditional<
                (i <= 32),
                uint32_t,
                uint64_t
            >::type
        >::type
    >::type type;
};   

int main() {
    std::cout << sizeof(best_type<2>::type) << std::endl;
    std::cout << sizeof(best_type<8>::type) << std::endl;
    std::cout << sizeof(best_type<15>::type) << std::endl;
    std::cout << sizeof(best_type<17>::type) << std::endl;
}