通常我有一些编译时常数,它也是变量假定的可能值的上限。因此,我有兴趣选择能够容纳这些价值的最小型。例如,我可能知道变量将适合于< -30 000,30 000>范围,所以在寻找合适的类型时,我会先使用signed short int。但是由于我在平台和编译器之间切换,我希望编译时断言检查常量上限值是否真的适合这些类型。 BOOST_STATIC_ASSERT(sizeof(T)> = required_number_of_bytes_for_number)工作正常,但问题是: 如何自动确定存储给定编译时常量(有符号或无符号)所需的字节数?我猜C宏可以做这个工作吗?谁能为我写这个? 我可能使用std :: numeric_limits :: max()和min()而不是计算字节但是我必须切换到运行时断言:(
答案 0 :(得分:4)
现在用c ++标记了这个,我建议使用Boost.Integer进行适当的类型选择。 boost::int_max_value_t< MyConstant >::least
会提供您要查找的类型。
答案 1 :(得分:0)
你如何避免这个问题:
BOOST_STATIC_ASSERT((1LL << (8*sizeof(T))) >= number);
答案 2 :(得分:0)
您可以使用以下代码。它仅适用于正8/16/32/64位整数。但您也可以对负值进行适当的更改。
template <typename T, T x> class TypeFor
{
template <T x>
struct BitsRequired {
static const size_t Value = 1 + BitsRequired<x/2>::Value;
};
template <>
struct BitsRequired<0> {
static const size_t Value = 0;
};
static const size_t Bits = BitsRequired<x>::Value;
static const size_t Bytes = (Bits + 7) / 8;
static const size_t Complexity = 1 + BitsRequired<Bytes-1>::Value;
template <size_t c> struct Internal {
};
template <> struct Internal<1> {
typedef UCHAR Type;
};
template <> struct Internal<2> {
typedef USHORT Type;
};
template <> struct Internal<3> {
typedef ULONG Type;
};
template <> struct Internal<4> {
typedef ULONGLONG Type;
};
public:
typedef typename Internal<Complexity>::Type Type;
};
TypeFor<UINT, 117>::Type x;
P.S。这是在MSVC下编译的。可能需要进行一些调整才能将其用于gcc / mingw / etc。
答案 3 :(得分:0)
BOOST_STATIC_ASSERT(int(60000)==60000)
怎么样?这将测试60000是否适合int。如果int是16位,int(60000)
是27232
。为了进行比较,这将被零扩展回32位长,并且可靠地失败。