【问题标题】:Compile-time (preprocessor) hashing of string字符串的编译时(预处理器)散列
【发布时间】:2011-02-19 01:44:19
【问题描述】:

有没有办法在编译时使用 C/C++ 预处理器(甚至模板元编程)创建字符串哈希?

例如UNIQUE_SALT("HelloWord", 3DES);

这个想法是 HelloWorld 不会出现在编译的二进制文件中,只是一个哈希。

编辑:这些声明中有许多分布在大型代码库中。

【问题讨论】:

  • 在编译时生成的唯一盐有点没抓住重点......

标签: hash c-preprocessor


【解决方案1】:

answer from michaeljt 对我不起作用,我得到了:

错误 C2131 表达式未计算为常量

我想出了这个,它对我有用(最长为 254,只有常量 char 数组):

#define CT 65599u
#define H2(s) (CT * s[0] + s[1])
#define H4(s) (CT * (CT * H2(s) + s[2]) + s[3])
#define H6(s) (CT * (CT * H4(s) + s[4]) + s[5])
#define H8(s) (CT * (CT * H6(s) + s[6]) + s[7])
#define H10(s) (CT * (CT * H8(s) + s[8]) + s[9])
#define H12(s) (CT * (CT * H10(s) + s[10]) + s[11])
#define H14(s) (CT * (CT * H12(s) + s[12]) + s[13])
#define H16(s) (CT * (CT * H14(s) + s[14]) + s[15])
#define H18(s) (CT * (CT * H16(s) + s[16]) + s[17])
#define H20(s) (CT * (CT * H18(s) + s[18]) + s[19])
#define H22(s) (CT * (CT * H20(s) + s[20]) + s[21])
#define H24(s) (CT * (CT * H22(s) + s[22]) + s[23])
#define H26(s) (CT * (CT * H24(s) + s[24]) + s[25])
#define H28(s) (CT * (CT * H26(s) + s[26]) + s[27])
#define H30(s) (CT * (CT * H28(s) + s[28]) + s[29])
#define H32(s) (CT * (CT * H30(s) + s[30]) + s[31])
#define H34(s) (CT * (CT * H32(s) + s[32]) + s[33])
#define H36(s) (CT * (CT * H34(s) + s[34]) + s[35])
#define H38(s) (CT * (CT * H36(s) + s[36]) + s[37])
#define H40(s) (CT * (CT * H38(s) + s[38]) + s[39])
#define H42(s) (CT * (CT * H40(s) + s[40]) + s[41])
#define H44(s) (CT * (CT * H42(s) + s[42]) + s[43])
#define H46(s) (CT * (CT * H44(s) + s[44]) + s[45])
#define H48(s) (CT * (CT * H46(s) + s[46]) + s[47])
#define H50(s) (CT * (CT * H48(s) + s[48]) + s[49])
#define H52(s) (CT * (CT * H50(s) + s[50]) + s[51])
#define H54(s) (CT * (CT * H52(s) + s[52]) + s[53])
#define H56(s) (CT * (CT * H54(s) + s[54]) + s[55])
#define H58(s) (CT * (CT * H56(s) + s[56]) + s[57])
#define H60(s) (CT * (CT * H58(s) + s[58]) + s[59])
#define H62(s) (CT * (CT * H60(s) + s[60]) + s[61])
#define H64(s) (CT * (CT * H62(s) + s[62]) + s[63])
#define H66(s) (CT * (CT * H64(s) + s[64]) + s[65])
#define H68(s) (CT * (CT * H66(s) + s[66]) + s[67])
#define H70(s) (CT * (CT * H68(s) + s[68]) + s[69])
#define H72(s) (CT * (CT * H70(s) + s[70]) + s[71])
#define H74(s) (CT * (CT * H72(s) + s[72]) + s[73])
#define H76(s) (CT * (CT * H74(s) + s[74]) + s[75])
#define H78(s) (CT * (CT * H76(s) + s[76]) + s[77])
#define H80(s) (CT * (CT * H78(s) + s[78]) + s[79])
#define H82(s) (CT * (CT * H80(s) + s[80]) + s[81])
#define H84(s) (CT * (CT * H82(s) + s[82]) + s[83])
#define H86(s) (CT * (CT * H84(s) + s[84]) + s[85])
#define H88(s) (CT * (CT * H86(s) + s[86]) + s[87])
#define H90(s) (CT * (CT * H88(s) + s[88]) + s[89])
#define H92(s) (CT * (CT * H90(s) + s[90]) + s[91])
#define H94(s) (CT * (CT * H92(s) + s[92]) + s[93])
#define H96(s) (CT * (CT * H94(s) + s[94]) + s[95])
#define H98(s) (CT * (CT * H96(s) + s[96]) + s[97])
#define H100(s) (CT * (CT * H98(s) + s[98]) + s[99])
#define H102(s) (CT * (CT * H100(s) + s[100]) + s[101])
#define H104(s) (CT * (CT * H102(s) + s[102]) + s[103])
#define H106(s) (CT * (CT * H104(s) + s[104]) + s[105])
#define H108(s) (CT * (CT * H106(s) + s[106]) + s[107])
#define H110(s) (CT * (CT * H108(s) + s[108]) + s[109])
#define H112(s) (CT * (CT * H110(s) + s[110]) + s[111])
#define H114(s) (CT * (CT * H112(s) + s[112]) + s[113])
#define H116(s) (CT * (CT * H114(s) + s[114]) + s[115])
#define H118(s) (CT * (CT * H116(s) + s[116]) + s[117])
#define H120(s) (CT * (CT * H118(s) + s[118]) + s[119])
#define H122(s) (CT * (CT * H120(s) + s[120]) + s[121])
#define H124(s) (CT * (CT * H122(s) + s[122]) + s[123])
#define H126(s) (CT * (CT * H124(s) + s[124]) + s[125])
#define H128(s) (CT * (CT * H126(s) + s[126]) + s[127])
#define H130(s) (CT * (CT * H128(s) + s[128]) + s[129])
#define H132(s) (CT * (CT * H130(s) + s[130]) + s[131])
#define H134(s) (CT * (CT * H132(s) + s[132]) + s[133])
#define H136(s) (CT * (CT * H134(s) + s[134]) + s[135])
#define H138(s) (CT * (CT * H136(s) + s[136]) + s[137])
#define H140(s) (CT * (CT * H138(s) + s[138]) + s[139])
#define H142(s) (CT * (CT * H140(s) + s[140]) + s[141])
#define H144(s) (CT * (CT * H142(s) + s[142]) + s[143])
#define H146(s) (CT * (CT * H144(s) + s[144]) + s[145])
#define H148(s) (CT * (CT * H146(s) + s[146]) + s[147])
#define H150(s) (CT * (CT * H148(s) + s[148]) + s[149])
#define H152(s) (CT * (CT * H150(s) + s[150]) + s[151])
#define H154(s) (CT * (CT * H152(s) + s[152]) + s[153])
#define H156(s) (CT * (CT * H154(s) + s[154]) + s[155])
#define H158(s) (CT * (CT * H156(s) + s[156]) + s[157])
#define H160(s) (CT * (CT * H158(s) + s[158]) + s[159])
#define H162(s) (CT * (CT * H160(s) + s[160]) + s[161])
#define H164(s) (CT * (CT * H162(s) + s[162]) + s[163])
#define H166(s) (CT * (CT * H164(s) + s[164]) + s[165])
#define H168(s) (CT * (CT * H166(s) + s[166]) + s[167])
#define H170(s) (CT * (CT * H168(s) + s[168]) + s[169])
#define H172(s) (CT * (CT * H170(s) + s[170]) + s[171])
#define H174(s) (CT * (CT * H172(s) + s[172]) + s[173])
#define H176(s) (CT * (CT * H174(s) + s[174]) + s[175])
#define H178(s) (CT * (CT * H176(s) + s[176]) + s[177])
#define H180(s) (CT * (CT * H178(s) + s[178]) + s[179])
#define H182(s) (CT * (CT * H180(s) + s[180]) + s[181])
#define H184(s) (CT * (CT * H182(s) + s[182]) + s[183])
#define H186(s) (CT * (CT * H184(s) + s[184]) + s[185])
#define H188(s) (CT * (CT * H186(s) + s[186]) + s[187])
#define H190(s) (CT * (CT * H188(s) + s[188]) + s[189])
#define H192(s) (CT * (CT * H190(s) + s[190]) + s[191])
#define H194(s) (CT * (CT * H192(s) + s[192]) + s[193])
#define H196(s) (CT * (CT * H194(s) + s[194]) + s[195])
#define H198(s) (CT * (CT * H196(s) + s[196]) + s[197])
#define H200(s) (CT * (CT * H198(s) + s[198]) + s[199])
#define H202(s) (CT * (CT * H200(s) + s[200]) + s[201])
#define H204(s) (CT * (CT * H202(s) + s[202]) + s[203])
#define H206(s) (CT * (CT * H204(s) + s[204]) + s[205])
#define H208(s) (CT * (CT * H206(s) + s[206]) + s[207])
#define H210(s) (CT * (CT * H208(s) + s[208]) + s[209])
#define H212(s) (CT * (CT * H210(s) + s[210]) + s[211])
#define H214(s) (CT * (CT * H212(s) + s[212]) + s[213])
#define H216(s) (CT * (CT * H214(s) + s[214]) + s[215])
#define H218(s) (CT * (CT * H216(s) + s[216]) + s[217])
#define H220(s) (CT * (CT * H218(s) + s[218]) + s[219])
#define H222(s) (CT * (CT * H220(s) + s[220]) + s[221])
#define H224(s) (CT * (CT * H222(s) + s[222]) + s[223])
#define H226(s) (CT * (CT * H224(s) + s[224]) + s[225])
#define H228(s) (CT * (CT * H226(s) + s[226]) + s[227])
#define H230(s) (CT * (CT * H228(s) + s[228]) + s[229])
#define H232(s) (CT * (CT * H230(s) + s[230]) + s[231])
#define H234(s) (CT * (CT * H232(s) + s[232]) + s[233])
#define H236(s) (CT * (CT * H234(s) + s[234]) + s[235])
#define H238(s) (CT * (CT * H236(s) + s[236]) + s[237])
#define H240(s) (CT * (CT * H238(s) + s[238]) + s[239])
#define H242(s) (CT * (CT * H240(s) + s[240]) + s[241])
#define H244(s) (CT * (CT * H242(s) + s[242]) + s[243])
#define H246(s) (CT * (CT * H244(s) + s[244]) + s[245])
#define H248(s) (CT * (CT * H246(s) + s[246]) + s[247])
#define H250(s) (CT * (CT * H248(s) + s[248]) + s[249])
#define H252(s) (CT * (CT * H250(s) + s[250]) + s[251])
#define H254(s) (CT * (CT * H252(s) + s[252]) + s[253])
#define STRHASH(s) ((unsigned int)\
( \
sizeof(s) == 1 ? s[0] \
: sizeof(s) == 2 ? H2(s) \
: sizeof(s) == 3 ? (CT * H2(s) + s[2]) \
: sizeof(s) == 4 ? H4(s) \
: sizeof(s) == 5 ? (CT * H4(s) + s[4]) \
: sizeof(s) == 6 ? H6(s) \
: sizeof(s) == 7 ? (CT * H6(s) + s[6]) \
: sizeof(s) == 8 ? H8(s) \
: sizeof(s) == 9 ? (CT * H8(s) + s[8]) \
: sizeof(s) == 10 ? H10(s) \
: sizeof(s) == 11 ? (CT * H10(s) + s[10]) \
: sizeof(s) == 12 ? H12(s) \
: sizeof(s) == 13 ? (CT * H12(s) + s[12]) \
: sizeof(s) == 14 ? H14(s) \
: sizeof(s) == 15 ? (CT * H14(s) + s[14]) \
: sizeof(s) == 16 ? H16(s) \
: sizeof(s) == 17 ? (CT * H16(s) + s[16]) \
: sizeof(s) == 18 ? H18(s) \
: sizeof(s) == 19 ? (CT * H18(s) + s[18]) \
: sizeof(s) == 20 ? H20(s) \
: sizeof(s) == 21 ? (CT * H20(s) + s[20]) \
: sizeof(s) == 22 ? H22(s) \
: sizeof(s) == 23 ? (CT * H22(s) + s[22]) \
: sizeof(s) == 24 ? H24(s) \
: sizeof(s) == 25 ? (CT * H24(s) + s[24]) \
: sizeof(s) == 26 ? H26(s) \
: sizeof(s) == 27 ? (CT * H26(s) + s[26]) \
: sizeof(s) == 28 ? H28(s) \
: sizeof(s) == 29 ? (CT * H28(s) + s[28]) \
: sizeof(s) == 30 ? H30(s) \
: sizeof(s) == 31 ? (CT * H30(s) + s[30]) \
: sizeof(s) == 32 ? H32(s) \
: sizeof(s) == 33 ? (CT * H32(s) + s[32]) \
: sizeof(s) == 34 ? H34(s) \
: sizeof(s) == 35 ? (CT * H34(s) + s[34]) \
: sizeof(s) == 36 ? H36(s) \
: sizeof(s) == 37 ? (CT * H36(s) + s[36]) \
: sizeof(s) == 38 ? H38(s) \
: sizeof(s) == 39 ? (CT * H38(s) + s[38]) \
: sizeof(s) == 40 ? H40(s) \
: sizeof(s) == 41 ? (CT * H40(s) + s[40]) \
: sizeof(s) == 42 ? H42(s) \
: sizeof(s) == 43 ? (CT * H42(s) + s[42]) \
: sizeof(s) == 44 ? H44(s) \
: sizeof(s) == 45 ? (CT * H44(s) + s[44]) \
: sizeof(s) == 46 ? H46(s) \
: sizeof(s) == 47 ? (CT * H46(s) + s[46]) \
: sizeof(s) == 48 ? H48(s) \
: sizeof(s) == 49 ? (CT * H48(s) + s[48]) \
: sizeof(s) == 50 ? H50(s) \
: sizeof(s) == 51 ? (CT * H50(s) + s[50]) \
: sizeof(s) == 52 ? H52(s) \
: sizeof(s) == 53 ? (CT * H52(s) + s[52]) \
: sizeof(s) == 54 ? H54(s) \
: sizeof(s) == 55 ? (CT * H54(s) + s[54]) \
: sizeof(s) == 56 ? H56(s) \
: sizeof(s) == 57 ? (CT * H56(s) + s[56]) \
: sizeof(s) == 58 ? H58(s) \
: sizeof(s) == 59 ? (CT * H58(s) + s[58]) \
: sizeof(s) == 60 ? H60(s) \
: sizeof(s) == 61 ? (CT * H60(s) + s[60]) \
: sizeof(s) == 62 ? H62(s) \
: sizeof(s) == 63 ? (CT * H62(s) + s[62]) \
: sizeof(s) == 64 ? H64(s) \
: sizeof(s) == 65 ? (CT * H64(s) + s[64]) \
: sizeof(s) == 66 ? H66(s) \
: sizeof(s) == 67 ? (CT * H66(s) + s[66]) \
: sizeof(s) == 68 ? H68(s) \
: sizeof(s) == 69 ? (CT * H68(s) + s[68]) \
: sizeof(s) == 70 ? H70(s) \
: sizeof(s) == 71 ? (CT * H70(s) + s[70]) \
: sizeof(s) == 72 ? H72(s) \
: sizeof(s) == 73 ? (CT * H72(s) + s[72]) \
: sizeof(s) == 74 ? H74(s) \
: sizeof(s) == 75 ? (CT * H74(s) + s[74]) \
: sizeof(s) == 76 ? H76(s) \
: sizeof(s) == 77 ? (CT * H76(s) + s[76]) \
: sizeof(s) == 78 ? H78(s) \
: sizeof(s) == 79 ? (CT * H78(s) + s[78]) \
: sizeof(s) == 80 ? H80(s) \
: sizeof(s) == 81 ? (CT * H80(s) + s[80]) \
: sizeof(s) == 82 ? H82(s) \
: sizeof(s) == 83 ? (CT * H82(s) + s[82]) \
: sizeof(s) == 84 ? H84(s) \
: sizeof(s) == 85 ? (CT * H84(s) + s[84]) \
: sizeof(s) == 86 ? H86(s) \
: sizeof(s) == 87 ? (CT * H86(s) + s[86]) \
: sizeof(s) == 88 ? H88(s) \
: sizeof(s) == 89 ? (CT * H88(s) + s[88]) \
: sizeof(s) == 90 ? H90(s) \
: sizeof(s) == 91 ? (CT * H90(s) + s[90]) \
: sizeof(s) == 92 ? H92(s) \
: sizeof(s) == 93 ? (CT * H92(s) + s[92]) \
: sizeof(s) == 94 ? H94(s) \
: sizeof(s) == 95 ? (CT * H94(s) + s[94]) \
: sizeof(s) == 96 ? H96(s) \
: sizeof(s) == 97 ? (CT * H96(s) + s[96]) \
: sizeof(s) == 98 ? H98(s) \
: sizeof(s) == 99 ? (CT * H98(s) + s[98]) \
: sizeof(s) == 100 ? H100(s) \
: sizeof(s) == 101 ? (CT * H100(s) + s[100]) \
: sizeof(s) == 102 ? H102(s) \
: sizeof(s) == 103 ? (CT * H102(s) + s[102]) \
: sizeof(s) == 104 ? H104(s) \
: sizeof(s) == 105 ? (CT * H104(s) + s[104]) \
: sizeof(s) == 106 ? H106(s) \
: sizeof(s) == 107 ? (CT * H106(s) + s[106]) \
: sizeof(s) == 108 ? H108(s) \
: sizeof(s) == 109 ? (CT * H108(s) + s[108]) \
: sizeof(s) == 110 ? H110(s) \
: sizeof(s) == 111 ? (CT * H110(s) + s[110]) \
: sizeof(s) == 112 ? H112(s) \
: sizeof(s) == 113 ? (CT * H112(s) + s[112]) \
: sizeof(s) == 114 ? H114(s) \
: sizeof(s) == 115 ? (CT * H114(s) + s[114]) \
: sizeof(s) == 116 ? H116(s) \
: sizeof(s) == 117 ? (CT * H116(s) + s[116]) \
: sizeof(s) == 118 ? H118(s) \
: sizeof(s) == 119 ? (CT * H118(s) + s[118]) \
: sizeof(s) == 120 ? H120(s) \
: sizeof(s) == 121 ? (CT * H120(s) + s[120]) \
: sizeof(s) == 122 ? H122(s) \
: sizeof(s) == 123 ? (CT * H122(s) + s[122]) \
: sizeof(s) == 124 ? H124(s) \
: sizeof(s) == 125 ? (CT * H124(s) + s[124]) \
: sizeof(s) == 126 ? H126(s) \
: sizeof(s) == 127 ? (CT * H126(s) + s[126]) \
: sizeof(s) == 128 ? H128(s) \
: sizeof(s) == 129 ? (CT * H128(s) + s[128]) \
: sizeof(s) == 130 ? H130(s) \
: sizeof(s) == 131 ? (CT * H130(s) + s[130]) \
: sizeof(s) == 132 ? H132(s) \
: sizeof(s) == 133 ? (CT * H132(s) + s[132]) \
: sizeof(s) == 134 ? H134(s) \
: sizeof(s) == 135 ? (CT * H134(s) + s[134]) \
: sizeof(s) == 136 ? H136(s) \
: sizeof(s) == 137 ? (CT * H136(s) + s[136]) \
: sizeof(s) == 138 ? H138(s) \
: sizeof(s) == 139 ? (CT * H138(s) + s[138]) \
: sizeof(s) == 140 ? H140(s) \
: sizeof(s) == 141 ? (CT * H140(s) + s[140]) \
: sizeof(s) == 142 ? H142(s) \
: sizeof(s) == 143 ? (CT * H142(s) + s[142]) \
: sizeof(s) == 144 ? H144(s) \
: sizeof(s) == 145 ? (CT * H144(s) + s[144]) \
: sizeof(s) == 146 ? H146(s) \
: sizeof(s) == 147 ? (CT * H146(s) + s[146]) \
: sizeof(s) == 148 ? H148(s) \
: sizeof(s) == 149 ? (CT * H148(s) + s[148]) \
: sizeof(s) == 150 ? H150(s) \
: sizeof(s) == 151 ? (CT * H150(s) + s[150]) \
: sizeof(s) == 152 ? H152(s) \
: sizeof(s) == 153 ? (CT * H152(s) + s[152]) \
: sizeof(s) == 154 ? H154(s) \
: sizeof(s) == 155 ? (CT * H154(s) + s[154]) \
: sizeof(s) == 156 ? H156(s) \
: sizeof(s) == 157 ? (CT * H156(s) + s[156]) \
: sizeof(s) == 158 ? H158(s) \
: sizeof(s) == 159 ? (CT * H158(s) + s[158]) \
: sizeof(s) == 160 ? H160(s) \
: sizeof(s) == 161 ? (CT * H160(s) + s[160]) \
: sizeof(s) == 162 ? H162(s) \
: sizeof(s) == 163 ? (CT * H162(s) + s[162]) \
: sizeof(s) == 164 ? H164(s) \
: sizeof(s) == 165 ? (CT * H164(s) + s[164]) \
: sizeof(s) == 166 ? H166(s) \
: sizeof(s) == 167 ? (CT * H166(s) + s[166]) \
: sizeof(s) == 168 ? H168(s) \
: sizeof(s) == 169 ? (CT * H168(s) + s[168]) \
: sizeof(s) == 170 ? H170(s) \
: sizeof(s) == 171 ? (CT * H170(s) + s[170]) \
: sizeof(s) == 172 ? H172(s) \
: sizeof(s) == 173 ? (CT * H172(s) + s[172]) \
: sizeof(s) == 174 ? H174(s) \
: sizeof(s) == 175 ? (CT * H174(s) + s[174]) \
: sizeof(s) == 176 ? H176(s) \
: sizeof(s) == 177 ? (CT * H176(s) + s[176]) \
: sizeof(s) == 178 ? H178(s) \
: sizeof(s) == 179 ? (CT * H178(s) + s[178]) \
: sizeof(s) == 180 ? H180(s) \
: sizeof(s) == 181 ? (CT * H180(s) + s[180]) \
: sizeof(s) == 182 ? H182(s) \
: sizeof(s) == 183 ? (CT * H182(s) + s[182]) \
: sizeof(s) == 184 ? H184(s) \
: sizeof(s) == 185 ? (CT * H184(s) + s[184]) \
: sizeof(s) == 186 ? H186(s) \
: sizeof(s) == 187 ? (CT * H186(s) + s[186]) \
: sizeof(s) == 188 ? H188(s) \
: sizeof(s) == 189 ? (CT * H188(s) + s[188]) \
: sizeof(s) == 190 ? H190(s) \
: sizeof(s) == 191 ? (CT * H190(s) + s[190]) \
: sizeof(s) == 192 ? H192(s) \
: sizeof(s) == 193 ? (CT * H192(s) + s[192]) \
: sizeof(s) == 194 ? H194(s) \
: sizeof(s) == 195 ? (CT * H194(s) + s[194]) \
: sizeof(s) == 196 ? H196(s) \
: sizeof(s) == 197 ? (CT * H196(s) + s[196]) \
: sizeof(s) == 198 ? H198(s) \
: sizeof(s) == 199 ? (CT * H198(s) + s[198]) \
: sizeof(s) == 200 ? H200(s) \
: sizeof(s) == 201 ? (CT * H200(s) + s[200]) \
: sizeof(s) == 202 ? H202(s) \
: sizeof(s) == 203 ? (CT * H202(s) + s[202]) \
: sizeof(s) == 204 ? H204(s) \
: sizeof(s) == 205 ? (CT * H204(s) + s[204]) \
: sizeof(s) == 206 ? H206(s) \
: sizeof(s) == 207 ? (CT * H206(s) + s[206]) \
: sizeof(s) == 208 ? H208(s) \
: sizeof(s) == 209 ? (CT * H208(s) + s[208]) \
: sizeof(s) == 210 ? H210(s) \
: sizeof(s) == 211 ? (CT * H210(s) + s[210]) \
: sizeof(s) == 212 ? H212(s) \
: sizeof(s) == 213 ? (CT * H212(s) + s[212]) \
: sizeof(s) == 214 ? H214(s) \
: sizeof(s) == 215 ? (CT * H214(s) + s[214]) \
: sizeof(s) == 216 ? H216(s) \
: sizeof(s) == 217 ? (CT * H216(s) + s[216]) \
: sizeof(s) == 218 ? H218(s) \
: sizeof(s) == 219 ? (CT * H218(s) + s[218]) \
: sizeof(s) == 220 ? H220(s) \
: sizeof(s) == 221 ? (CT * H220(s) + s[220]) \
: sizeof(s) == 222 ? H222(s) \
: sizeof(s) == 223 ? (CT * H222(s) + s[222]) \
: sizeof(s) == 224 ? H224(s) \
: sizeof(s) == 225 ? (CT * H224(s) + s[224]) \
: sizeof(s) == 226 ? H226(s) \
: sizeof(s) == 227 ? (CT * H226(s) + s[226]) \
: sizeof(s) == 228 ? H228(s) \
: sizeof(s) == 229 ? (CT * H228(s) + s[228]) \
: sizeof(s) == 230 ? H230(s) \
: sizeof(s) == 231 ? (CT * H230(s) + s[230]) \
: sizeof(s) == 232 ? H232(s) \
: sizeof(s) == 233 ? (CT * H232(s) + s[232]) \
: sizeof(s) == 234 ? H234(s) \
: sizeof(s) == 235 ? (CT * H234(s) + s[234]) \
: sizeof(s) == 236 ? H236(s) \
: sizeof(s) == 237 ? (CT * H236(s) + s[236]) \
: sizeof(s) == 238 ? H238(s) \
: sizeof(s) == 239 ? (CT * H238(s) + s[238]) \
: sizeof(s) == 240 ? H240(s) \
: sizeof(s) == 241 ? (CT * H240(s) + s[240]) \
: sizeof(s) == 242 ? H242(s) \
: sizeof(s) == 243 ? (CT * H242(s) + s[242]) \
: sizeof(s) == 244 ? H244(s) \
: sizeof(s) == 245 ? (CT * H244(s) + s[244]) \
: sizeof(s) == 246 ? H246(s) \
: sizeof(s) == 247 ? (CT * H246(s) + s[246]) \
: sizeof(s) == 248 ? H248(s) \
: sizeof(s) == 249 ? (CT * H248(s) + s[248]) \
: sizeof(s) == 250 ? H250(s) \
: sizeof(s) == 251 ? (CT * H250(s) + s[250]) \
: sizeof(s) == 252 ? H252(s) \
: sizeof(s) == 253 ? (CT * H252(s) + s[252]) \
: sizeof(s) == 254 ? H254(s) \
: -1 \
))

【讨论】:

    【解决方案2】:

    这就是我使用 C++0x 执行此编译时字符串哈希的方法:

    class StringHash
    {
    public:
        template <unsigned N, unsigned I>
        struct HashHelper
        {
            constexpr static unsigned Calculate(const char (&str)[N])
            {
                return (HashHelper<N, I - 1>::Calculate(str) ^ (str[I - 1] & 0xFF)) * StringHash::PRIME;
            }
        };
    
        template <unsigned N>
        struct HashHelper<N, 1>
        {
            constexpr static unsigned Calculate(const char (&str)[N])
            {
                return (StringHash::OFFSET ^ (str[0] & 0xFF)) * StringHash::PRIME;
            }
        };
    
        template<unsigned N>
        constexpr static unsigned StaticHash(const char (&str)[N])
        {
            return HashHelper<N, N>::Calculate(str);
        }
    
        static const unsigned OFFSET = 0x01234567;
        static const unsigned PRIME = 0x89ABCDEF;
    }
    

    用法:

    static hash = StringHash::StaticHash("Hello"); // You may even use this expression in `switch case`
    

    【讨论】:

      【解决方案3】:

      使用 C++0x,#1#2 中的答案涵盖了这一点。

      在 C++03 中没有编译时字符串处理。使用预处理器,您无法将字符串分成标记,使用模板您无法访问单个字符。不过有人讨论了推测的approach using C++0x

      你可以为 C++03 做的是按字符传递字符串(可能使用多字符文字):

      foo = hash<3DES, str<'a','b','c'> >::result;
      // or:
      foo = hash<3DES, str<'abc','def'> >::result;
      

      ...或者只是将其作为预构建步骤。

      【讨论】:

      • "hash >::result" 是如何工作的,为什么你不能做"hash >::result"?
      • @Ashirus:这些是多字符文字,类型为int“实现定义值”。更长的值根本不适合int,您仍然需要手动获取单独的字符值。
      • 很抱歉搅动了一篇旧帖子,但是是的,这在 C++ 中是可能的。 C++0X 使以下方法更简洁,但使用元模板编程,您可以做到这一点,尽管是逐个字符,如下面的示例所示。正如您所指出的,在 C++0x 中,您可以一次处理更多字符。
      • @leet:我上面已经说过,你不能在编译时处理字符串或字符串文字,但你可以处理字符列表。这正是您所做的,我的示例显示了。
      • @Georg 对不起,我误解了你的措辞,我不是那么直白;你是对的,就你不能处理“字符串”而言,你只能处理单个'c','h','a','r','s'。当时我在一般意义上(而不是作为程序员)认为可以处理字符串,您只需手动将其分解以进行编译时处理。
      【解决方案4】:

      声称无法在编译时解析字符串的答案是错误的。编译时无法解析字符指针,但字符串字面量不是字符指针;它们是长度是类型的一部分的字符数组。很容易忘记这一点,因为在大多数情况下,让它们衰减为 char* 会更有用。但他们并不是这样开始的。

      啊,但是如何实际定义一个采用固定长度字符数组的函数,特别是如果我们真的更愿意在任意长度的字符串上使用它?这就是模板参数推导派上用场的地方:

      template<size_t L>
      constexpr int hash(const char (&str)[L], int n = L - 1) {
          // hash goes here. You can define recursively as a
          // function of str[n] and hash(str, n-1). Remember to
          // treat 0 as a special case.
      }
      

      这应该让你开始。显然,哈希本身需要足够简单才能进行编译时计算,但这可能没问题。

      【讨论】:

        【解决方案5】:

        虽然这不是问题的正确答案,但请参阅此博客条目以获取纯粹作为 C 宏实现的最多 256 个字符的字符串的哈希函数示例:

        http://lolengine.net/blog/2011/12/20/cpp-constant-string-hash

        以下是博客中的实际代码:

        #include <string.h>
        #include <stdint.h>
        #include <stdio.h>
        
        #define H1(s,i,x)   (x*65599u+(uint8_t)s[(i)<strlen(s)?strlen(s)-1-(i):strlen(s)])
        #define H4(s,i,x)   H1(s,i,H1(s,i+1,H1(s,i+2,H1(s,i+3,x))))
        #define H16(s,i,x)  H4(s,i,H4(s,i+4,H4(s,i+8,H4(s,i+12,x))))
        #define H64(s,i,x)  H16(s,i,H16(s,i+16,H16(s,i+32,H16(s,i+48,x))))
        #define H256(s,i,x) H64(s,i,H64(s,i+64,H64(s,i+128,H64(s,i+192,x))))
        
        #define HASH(s)    ((uint32_t)(H256(s,0,0)^(H256(s,0,0)>>16)))
        

        如果您提前知道您只会将它用于静态字符串,您可以将 strlen() 替换为 sizeof()。

        【讨论】:

          【解决方案6】:

          我偶然发现了一个使用良好的 'ol C++ 标准的解决方案(我不确定它被认为是什么版本,但我们只是说这个解决方案在 Visual Studio 中有效)。这是链接:link

          此外,这里有一个使用上述技术的 JSHash 函数的简短版本。这里显示的最多支持 4 个字符,但您可以添加任意数量的字符。

          template<const char A = 0, const char B = 0, const char C = 0, const char D = 0>
          struct cHash
          {
              template<const char C, size_t hash = 1315423911>
              struct HashCalc
              {
                  enum { value = (C == 0) ? hash : hash ^ ((hash << 5) + C + (hash >> 2)) };
              };
          
              enum { value = HashCalc<D,HashCalc<C,HashCalc<B,HashCalc<A>::value>::value>::value>::value };
          };
          

          如前所述,因为这是一个编译时哈希,你可以这样做:

          namespace Section
          {
              enum Enum
              {
                  Player = cHash<'p','l','a','y'>::value
              };
          }
          

          这不是最优雅的解决方案,所以我计划在这个领域做更多的研究,但是由于这是我在 VisualStudio2010 中唯一可以工作的东西,所以就我目前的项目而言,我有点受限.

          【讨论】:

            【解决方案7】:

            即使这不能(合理地)使用预处理器完成,如果您使用字符串文字或将其声明为 static const 并且没有创建任何持久引用,编译器可能会继续执行所有操作如果您使用优化进行编译,则生成结果并省略目标文件中的字符串的数学运算。最难的部分是你不能让初始化全局或静态变量的代码太复杂,否则编译器会说“嘿,你!你不知道你不能在函数之外使用 for 循环?”。

            【讨论】:

            • 这是一个很好的观点,但是我需要确定没有引用,因为有很多声明并且二进制大小非常重要。
            • 我真的不认为你的编译器会优化散列算法,即使所有数据都是 const 的——它们很聪明,但几乎没有那么聪明。
            【解决方案8】:

            为什么不将生成哈希作为构建过程的一部分?您可以编写一个简单的批处理文件来生成哈希(假设您有一个程序来做这样的事情 - 如果没有,请编写一个)并让它输出一个预处理器指令,例如:

            #define MY_HASH 123456789 
            

            到一个 .h 文件,然后在您的应用程序中获得#included。

            【讨论】:

            • 我的问题不是生成哈希,而是在编译时查找并用它们的哈希替换这些字符串。我能想到的唯一方法是使用预处理器破解。源代码管理中有很多这样的 UNIQUE_SALT("Some string", xxx) 声明。
            • @Ashirus 好吧,我仍然认为处理它们的最好方法是集中它们,然后以某种方式生成所需的定义。
            • 预构建步骤很简单!毕竟,这只是一些模式匹配/替换。任何脚本语言都允许你这样做,并且它会变得像使用预处理器一样透明。
            • @Neil。他们不能集中。它们分布在源代码中(超过 1M LOC,不受我控制)。这就是问题空间。
            • @All 我很欣赏这些替代方法,但实际上,您要求我重新定义问题空间并假设我对代码库和工具链有一定程度的控制,而我根本没有,但谢谢无论如何。
            【解决方案9】:

            这可以通过 Boost.MPL 完成,但它可能不是您所追求的哈希类型。

            http://arcticinteractive.com/2009/04/18/compile-time-string-hashing-boost-mpl/

            【讨论】:

            • 谢谢,这已经很接近了,但是我猜根据 Georg 的回答,当前的 C++ 根本就没有能力。我想这里关于 SO 的其他类似问题应该提醒我这一点。如果我能接受两个答案,我也会接受你的。
            猜你喜欢
            • 2011-06-25
            • 2011-09-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-09-18
            • 1970-01-01
            • 1970-01-01
            • 2019-06-21
            相关资源
            最近更新 更多