由于其他模块把一个二维数据存成的一维数组, 给我传参时会给我首地址和数据的长宽. 如test1()
所示,我可以建一个二维数组的指针去指向数据的头, 并对数据进行操作. 所以我就在想能否写一个函数去完成test1()
的工作. 在test2()
函数里是时可以完成test1()
的工作, 但是返回值并没有达到工作预期. 使用auto result
只能访问到数组第一个元素, 使用auto &result
无法通过编译.
环境:
在 MSVC 2019 编译器下 test1()
的代码无法通过编译, 会提示数组的边界必须在编译期确定.
问题:
test1()
中算是运行期间创建了一个类型吗?test1()
中前两行的代码并将数据传出去?#include <iostream>
#include <vector>
void test1(float *raw, int sizex, int sizey)
{
using DataType = float[sizex][sizey];
auto &data = *reinterpret_cast<DataType *>(raw); // 编译通过, 并可以使用迭代器
// auto &data = *reinterpret_cast<(float *)[sizex][sizey]>(raw);
// 编译无法通过, 错误如下:
// error: Expected a type
for (auto &row: data)
{
for (auto &item: row)
{
std::cout << item << " ";
}
std::cout << std::endl;
}
// 输出:
// 0 1 2 3
// 4 5 6 7
// 8 9 10 11
}
template <typename T>
auto test2(T *t, int sizex, int sizey)
{
using DataType = T[sizex][sizey];
auto ptr = reinterpret_cast<DataType *>(t);
return ptr;
}
int main()
{
int sizex = 3;
int sizey = 4;
std::vector<float> vc(sizex * sizey);
for (int i = 0; i < vc.size(); ++i)
vc[i] = i;
test1(vc.data(), sizex, sizey);
// auto &result = *test2(vc.data(), sizex, sizey);
// 编译无法通过, 报错如下:
// In function 'int main()':
// In function 'int main()':
// internal compiler error: in expand_expr_real_1, at expr.c:9908
// using DataType = T[sizex][sizey];
// ^
// auto result = test2(vc.data(), sizex, sizey);
// 编译可以通过, 但 result 不能向上面一样使用迭代器, debug 下显示 *result 的类型为 float[1][1]
// auto &result2 = *test2(vc.data(), sizex, sizey);;
// 编译无法通过, 还是报错 internal compiler error: in expand_expr_real_1, at expr.c:9908
return 0;
}
1
inhzus 2023-06-21 14:34:37 +08:00
C-style array 的大小就应该是 constant expression... 不要钻这个牛角尖,不要写 mingw 方言... 不如老老实实就用 (T**, size_x, size_y) 来替代你的 T[size_x][size_y] *
|
2
Thymolblue OP @inhzus 其他模块给我的就只有数据块头的地址,不是很好更改。其实去计算访问的每个元素的地址也可以,但是如果能把这个指针转成二维数组的话我就可以对数据封装一下,后面的计算会简化很多。
|
3
ysc3839 2023-06-21 15:15:59 +08:00 via Android 1
你需要 C++23 的 std::mdspan 。即使不能升级编译器,也有参考实现可以用。
|
4
hankai17 2023-06-21 15:19:20 +08:00
constexpr int sizex
|
5
Thymolblue OP @ysc3839 感谢,本来我是想用 boost::multiarray 的,但是 multiarray 的访问效率太低。如果 std::mdspan 能达到接近直接访问二维数组的速度的话应该就解决问题了。
|
6
Thymolblue OP @hankai17 传入的数据大小是变化了,没法在编译期确定。
|