使用模板元在编译期间进行字节顺序的判断并且转换为相应字节顺序(大小端法转换)(原)
首先,开篇我先简单提提什么是模板元编程.模板元编程就是使用模板,在编译期间计算出一定的结果.例如我们在代码里面写有
int fun(int x,int y){ return x + y; } assert(fun(100, 20) == 120);
可能大家都会写过这样的函数,在这个时候你会觉得与其fun(100,20)这样调用,不如直接写120,那肯定会让程序快点
但是,问题可能不会那么简单,例如你想在代码里面表达654M这个大小,但是你又不想写 685768704 这样一个奇怪的数字进去你的代码.
问题可能会比现在你所看到的或者想到的更加复杂.例如你想输入一个2维数组,然后累加里面所有的数,你总不可能去算吧?但是放在运行时计算也会让程序变慢,
这种一开始就能知道的值为什么我们不能在编译的时候算好呢?
模板元就能够达到这个效果.
对于刚刚那个简单的相加的函数,我们可以给出简单的模板元函数
template<int x, int y> struct fun{ const static int _ret_val = x + y; } assert(fun<100, 20>::_ret_val == 120);
看,这样就可以很优雅地预先算好这个值
好了,下面开始正题.解释我都写在代码里面的注释里,下面上代码
1 // Copyright (C) 2012/12/15 fish 2 // 3 // 4 // 5 6 #ifndef _FISH_ENDIAN_H_ 7 #define _FISH_ENDIAN_H_ 8 9 #ifdef _MSC_VER 10 #define IS_BIG_ENDIAN false 11 //#elif 12 //这里定义其他平台 13 //本人对除windows平台以外的平台不熟悉 14 //望有心人看到帮忙补充 15 //谢谢 16 #endif 17 18 struct check_endian{ 19 const static bool _is_big_endian = IS_BIG_ENDIAN; 20 const static bool _is_little_endian = !IS_BIG_ENDIAN; 21 }; 22 23 //字节顺序转换模板函数 24 template<unsigned int i> 25 struct _change_endian{ 26 27 //分别取出1,2,3,4个字节,然后交换 28 const static unsigned int _i1 = i >> 24; 29 const static unsigned int _i2 = ((i << 8) >> 24) << 8; 30 const static unsigned int _i3 = ((i << 16) >> 24) << 16; 31 const static unsigned int _i4 = (i << 24); 32 33 const static unsigned int _ret_val = _i1 + _i2 + _i3 + _i4; 34 }; 35 36 ////////////////////////////////////////////////////////////////////////// 37 //转换为小端法 38 //其中有默认模板参数,使用了check_endian判断是哪种字节顺序 39 template<unsigned int i, bool _is_little_endian = check_endian::_is_little_endian> 40 struct to_little_endian_int32{ 41 42 }; 43 44 45 //发现本平台已经是小端法则什么也不做返回 46 template<unsigned int i> 47 struct to_little_endian_int32<i, true>{ 48 const static unsigned int _ret_val = i; 49 }; 50 51 //否则调用_change_endian转换字节顺序 52 template<unsigned int i> 53 struct to_little_endian_int32<i, false>{ 54 const static unsigned int _ret_val = _change_endian<i>::_ret_val; 55 }; 56 ////////////////////////////////////////////////////////////////////////// 57 58 59 ////////////////////////////////////////////////////////////////////////// 60 //转换为大端法 61 template<unsigned int i, bool _is_big_endian = check_endian::_is_big_endian> 62 struct to_big_endian_int32{ 63 64 }; 65 66 //发现本平台已经是大端法则什么也不做返回 67 template<unsigned int i> 68 struct to_big_endian_int32<i, true>{ 69 const static unsigned int _ret_val = i; 70 }; 71 72 //否则调用_change_endian转换字节顺序 73 template<unsigned int i> 74 struct to_big_endian_int32<i, false>{ 75 const static unsigned int _ret_val = _change_endian<i>::_ret_val; 76 }; 77 ////////////////////////////////////////////////////////////////////////// 78 79 #endif //_FISH_ENDIAN_H_
模板元非常忠实地帮我们计算出结果,善用模板元将会在大工程里面对我们有很大帮助.