为什么代码
void fcn(int *twoDArrayPtr, const int dim1, const int dim2) {
int (*array)[dim2] = reinterpret_cast<int (*)[dim2]>(twoDArrayPtr);
}
int main() {
return 0;
}
生成编译器错误
error: cannot initialize a variable of type 'int (*)[dim2]' with
an rvalue of type 'int (*)[dim2]'
类型是相同的,所以我认为可以执行任务。由于int (*)[dim2]
是一个指向大小为dim2
的数组的指针,因此可能是一个指向一堆大小为dim2
的数组的指针,这些数组在指针可索引的连续内存中,我会认为这应该工作。
我在Mac OS / X上使用clang ++,其中包含以下版本信息:
Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn) Target: x86_64-apple-darwin14.0.0 Thread model: posix
答案 0 :(得分:2)
dim2
不是编译时常量,并且在C ++中不存在VLA(可变长度数组)。其他一些编译器(如gcc)具有语言扩展,允许在C ++中使用VLA,但clang的行为符合标准。
您可以使用为您执行地址转换的类(或类模板)来解决此问题,例如
// This is very rudimentary, but it's a point to start.
template<typename T>
class array2d_ref {
public:
array2d_ref(T *p, std::size_t dim) : data_(p), dim_(dim) { }
T *operator[](std::size_t i) { return &data_[i * dim_]; }
private:
T *data_;
std::size_t dim_;
};
...
array2d_ref<int> array(twoDArrayPtr, dim2);
但我担心除非你在编译时知道数组的维度,否则不可能(可移植地)拥有指向数组的指针。
答案 1 :(得分:1)
当您在演员表中使用dim2
作为数组维度时,您尝试使用C99的可变长度数组(VLA)功能。 (例如,gcc支持扩展名:https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html。)
好消息,你现在不能这样做,但是你很快就可以引入C++14's Runtime Sized Arrays。
有关引言:
运行时大小的数组提供与C99的VLA相同的语法和性能......请记住,运行时大小的数组与C99的VLA并不完全相同。 C ++ 14功能更加内敛,同样也是如此。具体而言,排除以下属性:
- 运行时大小的多维数组
- 对函数声明符语法的修改
- 的大小
sizeof(a)
是运行时评估的表达式,返回typedef int a[n];
评估n
并将其传递给typedef
所以你的代码很快就会合法,大约是C ++ 14。
我已经在Visual Studio 2015测试版上试用了它,遗憾的是在撰写本文时它不受支持:(
答案 2 :(得分:0)
虽然clang不支持可变长度数组,但有一种解决方法。以下用clang ++ 4.0.0编译:
void fcn(int *twoDArrayPtr, const int dim1, const int dim2) {
using array_type = int (*)[dim2];
array_type array = reinterpret_cast<array_type>(twoDArrayPtr);
}
int main() {
return 0;
}
我不确定为什么这个别名声明应该有所不同。这看起来肯定不一致。