2012-02-24 65 views
0

下面的代码不编译C++非常量为const铸造编译错误

void aaa(const int **a) { 
} 

int *a[] = {new int[2]}; 
aaa(a); 

我 “不能从转换参数1 'INT [1]' 至“const int的*” 在VS2010和在GCC类似的错误

当我改变我的声明:

int const *a[] = {new int[2]}; 

const int *a[] = {new int[2]}; 

它编译,但我不明白为什么它不接受非const的变量声明

回答

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的地方,告诉编译器 ,你知道你在做什么,这是不是一个真正的问题。)

+0

也许'AAA(PA)'应该是' aaa(pa)' – bitstore 2012-02-24 15:33:47

+0

@tinybit或者它的声明应该是'int * pa;',调用后的使用应该是'* pa = 0;'。我将编辑修复我的答案中的代码。感谢您发现这一点。 – 2012-02-24 16:44:36

2

功能aaa需要一个指针到指针到恒-INT。 您的变量a是一个指向int指针的指针。 将后者分配给前者是错误的。

int const *a[]const int *a[]实际上是相同的东西,匹配的签名aaa。如果你试过int * const a[],那将是一个不同的类型(pointer-to-constant-pointer-to-int),你会再次触发类型错误。

如果您希望函数aaa采用常量指针指向int的指针,则需要编写aaa(int ** const a),但对参数值的常量实际上并不影响可调用的内容。


编辑:“但不是常量性暗示加 - 与隐式转换完成(这是实际的问题)?”

常量性可以被默认添加到你的价值通过,例如

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在他的回答中解释得更好。