C++模板类get()返回数组引用/引用出错求修复方案
问题分析与修复方案
咱们来一步步拆解你遇到的问题,先看代码里的核心错误:
错误原因
当Size != 1时,你用reinterpret_cast<SampleType>(pos)把ComponentType*直接转成数组引用是完全错误的。这里的SampleType是ComponentType(&)[Size](对Size元素组的引用),而直接把单个指针强制转成数组引用,会导致编译器错误地将指针的值解读为数组引用的绑定对象地址——从你的输出就能看出来,a.get()的地址和a对象本身的地址一致,说明返回的引用根本没指向pos指向的图像数据,而是指向了A对象自身的内存,自然读出来的都是垃圾值。
修复方案
要正确返回数组引用,你需要先把pos转换成指向Size元素组的指针,然后解引用这个指针得到数组引用。修改get()方法的else分支即可:
#include <iostream> #include <type_traits> template<typename ComponentType, uint8_t Size> struct A { using SampleType = typename std::conditional<Size == 1, ComponentType&, ComponentType(&)[Size]>::type; SampleType get() { if constexpr (Size == 1) { return *pos; } else { // 先转成指向Size元素组的指针,再解引用得到数组引用 return *reinterpret_cast<ComponentType(*)[Size]>(pos); } } void advance() { pos += Size; } ComponentType *pos; }; int main() { int i[10] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; A<int, 2> a{i}; std::cout << (size_t) &a << "\r\n"; std::cout << (size_t) a.get() << "\r\n"; std::cout << (size_t) a.pos << "\r\n"; std::cout << (size_t) i << "\r\n"; for(int c : a.get()) std::cout << c << " "; std::cout << "\n"; a.get()[1] = 1000; std::cout << i[1] << "\n"; // 应该输出1000 return 0; }
修复说明
- 当
Size != 1时,reinterpret_cast<ComponentType(*)[Size]>(pos)把ComponentType*(指向单个元素的指针)转换成ComponentType(*)[Size](指向Size个元素的数组的指针),这一步是安全的,因为你的pos确实指向连续Size个元素的起始位置。 - 解引用这个数组指针,就能得到
ComponentType(&)[Size]类型的数组引用,和SampleType完全匹配,返回后就能正确指向pos对应的图像数据。 - 修复后,范围for循环可以正常遍历数组,修改数组元素也会直接作用到原始的
i数组上,完全符合你的需求。
内容的提问来源于stack exchange,提问作者Chameleon
相关产品推荐
相关产品推荐

