我想在C++中泛化按位运算符,而无需考虑底层结构是数组。
作为实例...如果我想表示86位,我将使用类似以下结构的结构/类:
typedef struct {
uint64_t x[1];
uint16_t y[1];
uint8_t z[1];
} sampleStruct;
相反,如果我想分配160位,我将使用类似以下的结构:
typedef struct {
uint64_t x[2];
uint32_t y[1];
} sampleStruct;
我猜对于存储来说,一个琐碎但不是最佳的解决方案是假设所有块都是统一的,并分配最小的s.t。它覆盖了我正在执行的大小,但是即使是运动,我也更喜欢暴露的方式。
对我来说,显然我应该使用元编程来解决问题,因此我必须正确定义
template <int I>
typedef sampleStruct {
//something
}
但是我不是C++模板元编程的专家,所以我想了解什么是实现不同类型的示例struct varing的最佳方法。我知道如何根据自己的长度确定最佳的“覆盖”是这样的:
N64 = I/64;
RemN = I%64;
if(0 < RemN <= 8) {
add uint8_t var;
} else if (8 < RemN <= 16) {
add uint16_t var;
} else if (16 < RemN <= 24) {
add uint16_t var;
add uint8_t var;
} else {
//Similarly handle the other cases from 24 < RemN < 64
}
我该怎么做才能实现自己的目标?
我还猜想,与其他可能的实现方式相比,正确地大块设置可以使性能稍微好一些。
希望它足够清晰...
(假设C++ 11或更高版本)。
最佳答案
可能,但是涉及大量的打字。问题在于C++无法提供以元编程方式省略数据成员的方法(例如参见Conditional Inclusion/Exclusion of Data Members Inside Class Templates),因此您必须专门研究其存在与否:
template<int N64, bool P32, bool P16, bool P8>
struct sampleStructImpl;
template<int I>
using sampleStruct = sampleStructImpl<I/64, (I%64 >= 32), (I%32 >= 16), (I%16 >= 8)>;
各种局部特化(总共8个)如下所示:
template<int N64>
struct sampleStructImpl<N64, true, true, true>
{
std::uint64_t x[N64];
std::uint32_t y;
std::uint16_t z;
std::uint8_t w;
};
template<int N64>
struct sampleStructImpl<N64, true, true, false>
{
std::uint64_t x[N64];
std::uint32_t y;
std::uint16_t z;
// omit std::uint8_t w;
};
// 6 more partial specializations...
另外,由于零长度数组是非法的,因此,如果要允许
I
的值小于64,则必须专门研究N64
为零:template<>
struct sampleStructImpl<0, true, true, true>
{
// omit std::uint64_t x[0];
std::uint32_t y;
std::uint16_t z;
std::uint8_t w;
};
// 7 more specializations...
使用
std::array<std::uint8_t, (I + 7) / 8>
可能要简单得多,可能使用alignas
修饰符对它进行64位对齐。关于c++ - 用于优化存储/运行时算法的元编程,C++,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36330870/