我需要在编译时找出可以表示特定数字的最小无符号整数类型。像这样......
//////////////////////////////////////////////////////////////////////////
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
旨在为您提供至少Bits
大的最小无符号整数类型,它应该适用于任何高达64的值(不仅仅是8,16,32,64而且还可以1,4,13等)。
uint_least_bits
旨在为您提供表示max
所需的最少位数。
uint_least
?uint_least_bits
?bits
,min
和max
应该是哪种类型?如果答案是模板类型,我该如何防范无效输入?特征的确切结构无关紧要。随意废弃我提供的东西。我只需要提供一个数字并找回可以容纳它的最小无符号整数类型。
答案 0 :(得分:8)
我昨天做了这件事,真是巧合。我会把它留在这里,即使它不是完全你需要的东西(无论如何它修复了最好的整体类型的东西):
#include <type_traits>
#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;
};
然后,你会像这样使用它:
#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;
}
现场演示,here。
答案 1 :(得分:4)
如果你有constexpr
,这将有效:
#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;
}
如果你没有constexpr
,你可以将clp2翻译成模板元函数(这留给读者作为练习: - ))。
哦,免责声明:假设32位unsigned
。如果需要,这也可以概括。