【发布时间】:2013-07-23 18:40:54
【问题描述】:
假设我需要为 0...255 个值创建一个包含预先计算的位计数值(数字中 1 位的计数)的 LUT:
int CB_LUT[256] = {0, 1, 1, 2, ... 7, 8};
如果我不想使用硬编码值,我可以使用不错的模板解决方案How to count the number of set bits in a 32-bit integer?
template <int BITS>
int CountBits(int val)
{
return (val & 0x1) + CountBits<BITS-1>(val >> 1);
}
template<>
int CountBits<1>(int val)
{
return val & 0x1;
}
int CB_LUT[256] = {CountBits<8>(0), CountBits<8>(1) ... CountBits<8>(255)};
这个数组是在编译时完全计算出来的。有什么方法可以避免长列表,并使用某种模板甚至宏(对不起!)生成这样的数组,例如:
Generate(CB_LUT, 0, 255); // array declaration
...
cout << CB_LUT[255]; // should print 8
备注。这个问题不是关于在一个数字中计算 1 位,它只是作为示例使用。我想完全在代码中生成这样的数组,而不使用外部代码生成器。数组必须在编译时生成。
编辑。 为了克服编译器限制,我找到了以下解决方案,基于 Bartek Banachewicz 代码:
#define MACRO(z,n,text) CountBits<8>(n)
int CB_LUT[] = {
BOOST_PP_ENUM(128, MACRO, _)
};
#undef MACRO
#define MACRO(z,n,text) CountBits<8>(n+128)
int CB_LUT2[] = {
BOOST_PP_ENUM(128, MACRO, _)
};
#undef MACRO
for(int i = 0; i < 256; ++i) // use only CB_LUT
{
cout << CB_LUT[i] << endl;
}
我知道这可能是UB……
【问题讨论】:
-
您为什么不想要一个带有硬编码值的简单查找表?这有什么问题?
-
如果你不喜欢预处理器魔法,你可以试试可变参数模板魔法:stackoverflow.com/q/2978259/819272
标签: c++ templates boost boost-preprocessor