C ++非const到const转换编译错误

时间:2012-02-24 09:05:33

标签: c++ casting const-cast

以下代码无法编译

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变量声明

2 个答案:

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