我想保持类似数据的数组连续进行处理。为简化起见,假设我想将 s 数组与int
s 数组分开,char
这样当我想显示字符时,我可以连续循环遍历所有字符,而无需获取整数。现在两个数组的前 32 个索引都属于一个对象,接下来的 32 个索引属于另一个对象。我希望能够对数组应用一种“蓝图”或“千篇一律”,以将数组的每个“拥有”部分组合在一起。我的第一个想法是给每个对象一个链接到它的数组部分的成员变量,就像这样
struct NonTemp {
std::array<int, 32>& ints;
std::array<char, 32>& chars;
NonTemp(std::array<int, 32>& Ints, std::array<char, 32>& Chars) : ints(Ints), chars(Chars) {}
};
但我发现这样一个对象的大小在 32 位版本上是 8 个字节,在 64 位版本上是 16 个字节。它正在存储指针。这些地址在编译时是已知的,所以我想我应该能够用硬编码地址替换指针。模板非常适合让编译器解决这种问题,所以我尝试了这个:
template<std::array<int, 32>& ints, std::array<char, 32>& chars>
struct Temp {
std::array<int, 32>& GetInts() {
return ints;
}
std::array<char, 32>& GetChars() {
return chars;
}
};
std::array<int, 64> ints;
std::array<char, 62> chars;
void main() {
static std::array<int, 32>& proxyInts = *reinterpret_cast<std::array<int, 32>*>(&ints[32]);
static std::array<char, 32>& proxyChars = *reinterpret_cast<std::array<char, 32>*>(&chars[32]);
Temp<proxyInts, proxyChars> temp;
}
但是我得到一个编译器错误,指出需要一个编译时常量表达式。做了一些研究,我发现 stackoverflow 上的另一个答案可以解释原因:Reference as a non-type template argument。它声称引用变量不是 id 表达式(类似于字符串文字)并且不能用作模板参数。那么有没有办法解决这个问题?还是有更好的方法来完成我想做的事情?为了便于测试,我为这种情况提供了一些完整的代码:
/*
* Stores pointers to references, increases object size by pointer size each
*/
struct NonTemp {
std::array<int, 32>& ints;
std::array<char, 32>& chars;
NonTemp(std::array<int, 32>& Ints, std::array<char, 32>& Chars) : ints(Ints), chars(Chars) {}
};
template<std::array<int, 32>& ints, std::array<char, 32>& chars>
struct Temp {
std::array<int, 32>& GetInts() {
return ints;
}
std::array<char, 32>& GetChars() {
return chars;
}
};
/*
* Replaces references to in with hard coded addresses, does not add to object size
*/
template<int& in>
struct Attempt {
int& GetInt() {
return in;
}
};
std::array<int, 64> ints;
std::array<char, 62> chars;
int in;
void main() {
NonTemp nonTemp = NonTemp(*reinterpret_cast<std::array<int, 32>*>(&ints), *reinterpret_cast<std::array<char, 32>*>(&chars));
std::cout << "Size of NonTemp: " << sizeof(nonTemp) << std::endl;
static std::array<int, 32>& proxyInts = *reinterpret_cast<std::array<int, 32>*>(&ints[32]);
static std::array<char, 32>& proxyChars = *reinterpret_cast<std::array<char, 32>*>(&chars[32]);
Temp<proxyInts, proxyChars> temp;
std::cout << "Size of Temp: " << sizeof(temp) << std::endl;
temp.GetInts()[0] = 2;
Attempt<in> attempt;
std::cout << "Size of Attempt: " << sizeof(attempt) << std::endl;
attempt.GetInt() = 10;
std::cout << "In: " << in << std::endl;
std::cout << "GetInt(): " << attempt.GetInt() << std::endl;
for (uint32_t i = 0; i < 64; ++i) {
std::cout << "Arr[" << i << "]: " << ints[i] << std::endl;
}
}
作为附加说明,每个对象可能并不总是“拥有”数组中相同数量的元素,我希望有一种方法让具有相似数据的不同对象拥有不同大小的数组部分,但是当我在编译时已经知道所有对象实例时,仍然知道存在哪些成员,而不会浪费 RAM 存储指针。