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