int32
或者是 unsigned8_t
之类的固定字长类型显得非常必要, 而且让工程看起来很专业的样子. 然而, 由于标准库中没有, 项目之间又互相不信任, 结果是几乎每个库都会自定一套, 比如 boost 就有 int8_t
, int_least8_t
等类型, 而 Qt 更是拿出了叫做 qulonglong
的类型来卖萌. 虽然说是跨平台, 但是如果迁移平台时使用了错误版本的库呢? 因此有时依然需要写一个类似下面的程序来人肉验证int main()
{
std::cout << sizeof(int4_type) << " "
<< sizeof(int8_type) << std::endl;
return 0;
}
理想的解决方案是, 只需要这样一个模板就好了
template <int _SizeOf>
struct IWantAnIntegralTypeOf;
int main()
{
IWantAnIntegralTypeOf<4> this_is_a_4_bytes_int;
IWantAnIntegralTypeOf<8> this_is_a_8_bytes_int;
return 0;
}
这是完全可行的, 实际上, 可以把 C 支持的所有内建整数类型先拿出来, 组成一个类型链表来搜索, 像下面这样
struct __null__ {};
struct c_char {
typedef char type;
typedef __null__ next;
};
struct c_short {
typedef short type;
typedef c_char next;
};
struct c_int {
typedef int type;
typedef c_short next;
};
struct c_long {
typedef long type;
typedef c_int next;
};
struct c_long_long {
typedef long long type;
typedef c_long next;
};
struct __head__ {
typedef c_long_long next;
};
template <typename _TypeNode, int _SizeOf, bool _SizeMatched>
struct type_finder;
template <typename _TypeNode, int _SizeOf>
struct type_finder<_TypeNode, _SizeOf, true>
{
typedef typename _TypeNode::type type;
};
template <typename _TypeNode, int _SizeOf>
struct type_finder<_TypeNode, _SizeOf, false>
{
typedef
typename type_finder<
typename _TypeNode::next
, _SizeOf
, _SizeOf == sizeof(typename _TypeNode::next::type)>::type type;
};
template <int _SizeOf>
struct gimme_the_type {
typedef typename type_finder<__head__, _SizeOf, false>::type type;
};
template <int _SizeOf>
struct IWantAnIntegralTypeOf {
typedef typename gimme_the_type<_SizeOf>::type;
operator type& ()
{
return value;
}
operator type const& () const
{
return value;
}
IWantAnIntegralTypeOf(type init_value = 0)
: value(init_value)
{}
private:
type value;
};
#include <iostream>
struct __this_platform_does_not_support_such_a_type__ {
typedef void type;
};
struct c_char {
typedef char type;
typedef __this_platform_does_not_support_such_a_type__ next;
};
struct c_short {
typedef short type;
typedef c_char next;
};
struct c_int {
typedef int type;
typedef c_short next;
};
struct c_long {
typedef long type;
typedef c_int next;
};
struct c_long_long {
typedef long long type;
typedef c_long next;
};
template <typename _TypeNode, int _SizeOf, bool _SizeMatched>
struct type_finder;
template <typename _TypeNode, int _SizeOf>
struct type_finder<_TypeNode, _SizeOf, true>
{
typedef typename _TypeNode::type type;
};
template <typename _TypeNode, int _SizeOf>
struct type_finder<_TypeNode, _SizeOf, false>
{
typedef
typename type_finder<
typename _TypeNode::next
, _SizeOf
, _SizeOf == sizeof(typename _TypeNode::next::type)>::type type;
};
template <int _SizeOf>
class IWantAnIntegralTypeOf {
struct __head__ {
typedef c_long_long next;
};
typedef typename type_finder<__head__, _SizeOf, false>::type type;
type value;
public:
operator type& ()
{
return value;
}
operator type const& () const
{
return value;
}
IWantAnIntegralTypeOf(type init_value = 0)
: value(init_value)
{}
};
int main()
{
IWantAnIntegralTypeOf<2> i2(0x7fff);
std::cout << i2 << std::endl;
i2 += 1;
std::cout << i2 << std::endl;
return 0;
}