我在使用二维数组时遇到了一些问题。
static const int PATTERNS[20][4];
static void init_PATTERN()
{
// problem #1
int (&patterns)[20][4] = const_cast<int[20][4]>(PATTERNS);
...
}
extern void UsePattern(int a, const int** patterns, int patterns_size);
// problem #2
UsePattern(10, PATTERNS, sizeof(PATTERNS)/sizeof(PATTERNS[0]));
在第一个语句中,我需要将const
从二维数组PATTERNS
中删除。原因是init函数只被调用一次,而在剩下的代码中,PATTERNS
是严格只读的。
在第二个语句中,我需要将PATTERNS
数组传递给int**
参数。直接传递导致编译错误。
我已经解决了这个问题,就在@Andrey发布答案的同时。是的int[][]
无法投放到int**
。
它可以通过int*
转换为&(PATTERNS[0][0])
,并且必须使用行大小(行中元素的数量)修改函数原型。使用引用语法,数组可以const_cast
。
答案 0 :(得分:7)
首先,在C ++中没有强制转换为数组类型(或函数类型)。然而,这正是你想要做的。如果你想从某些东西中抛弃constness,你必须转换为指针或引用类型。在你的情况下,你有一个关于演员的接收端的引用,所以演员本身也必须是引用类型
int (&patterns)[20][4] = const_cast<int (&)[20][4]>(PATTERNS);
当然,正如Bill已经指出的那样,从常量对象中抛弃constness(然后尝试修改对象)会导致未定义的行为。
其次,二维数组不能作为int **
指针传递到任何地方。如果您希望将PATTERNS
传递到某个地方,可以将其作为const int (&)[20][4]
,const int (*)[20][4]
,const int [][4]
,const int (*)[4]
或与此类似的内容传递,但不能int **
。在SO上搜索和/或读取阵列上的一些FAQ以了解原因。这已被解释太多次以重复它。
答案 1 :(得分:1)
当您将PATTERNS
声明为const时,编译器可能会将其设置为只读内存。你不能安全地抛弃const,除非最初声明的项目没有const。
我猜你的编译器错误是cannot convert 'int (*)[4]' to 'int**' for argument '2' to 'void UsePattern(int, int**, int)'
?
答案 2 :(得分:1)
AndreyT的答案是完美的。我只想补充一点,我相信你会更好地使用在构造函数中执行init_PATTERN()
工作的类,并覆盖operator[]
以提供对数组元素的只读访问权。
当然,假设您可以更改UsePattern函数以获取对此类的引用,而不是指向int数组的指针。
答案 3 :(得分:1)
C ++数组很复杂。你不能只是抛弃它们并期望它们像某些语言一样工作。从另一个数组初始化数组的唯一方法是导航 for 循环并单独复制每个项目。这对于二维数组来说是双倍的(意味着你需要两个用于循环)。
看起来你正试图让它变得比它需要的更复杂。例如,如果每次运行程序时要分配给PATTERNS的值集都相同,则可以初始化二维变量,如下所示:
static const int foo[2][3] = {{11,12,13},{21,22,23}};
如果分配给PATTERNS的值集从一次执行到下一次执行不同,那么您应该尝试找到一种不同的方法来解决问题。我可能会将数据包装在一个类中,特别是如果您打算在代码中的其他地方使用类似大小的二维数组。