以下代码无法编译
void aaa(const int **a) {
}
int *a[] = {new int[2]};
aaa(a);
我得到“无法在VS2010中将'int [1]'中的参数1转换为'const int * ”以及gcc中的类似错误
当我将声明更改为:
int const *a[] = {new int[2]};
或
const int *a[] = {new int[2]};
它编译,但我不明白为什么它不接受非const变量声明
答案 0 :(得分:8)
a
的类型为int*[]
;你想要的类型是int const**
。
int*[]
转换为int**
,但这不会隐式转换为
int const**
。请考虑以下代码以了解原因:
static int const ci = 42;
void aaa( int const** out )
{
*out = &ci;
}
int
main()
{
int* pa;
aaa( &pa ); // NOT LEGAL, because...
*pa = 0; // would now change ci
std::cout << ci << std::endl;
return 0;
}
正如你所看到的,允许这种转换会破坏const 需要演员。
根据您的操作,您可能希望使用:
void aaa( int const* const* out );
将int**
隐式转换为int const *const *
是合法的。
(否则,你需要一个const_cast
来告诉编译器
你知道自己在做什么,而且这不是一个真正的问题。)
答案 1 :(得分:2)
函数aaa
期望指针指向constant-int。
您的变量a
是指向int的指针。
将后者分配给前者是错误的。
int const *a[]
和const int *a[]
实际上是相同的,匹配aaa
的签名。如果您尝试int * const a[]
,那将是一个不同的类型(指向常量指针指向int),您将再次触发类型错误。
如果你希望你的函数aaa
采用指向指针到int的常量指针,你需要编写aaa(int ** const a)
,但是对参数值有一个常量实际上没有对你可以打电话的影响。
编辑: “但不是隐式添加常量 - 使用隐式转换完成?(这是实际问题)”
可以将Constness隐式添加到您传递的值中,例如
void aaa(const int a) {}
int b=5;
aaa(b);
...或一个级别的指针
void aaa(const int* a) {}
int *b=new int;
aaa(b);
......但不能加深。例如,这是无效的:
void aaa(const int** a) {}
int* b=new int;
int** c=&b;
aaa(c);
我认为James Kanze在回答中解释得更好。