1

以下代码无法编译

void aaa(const int **a) {
}

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

我在 VS2010 中得到“无法将参数 1 从 'int [1]' 转换为 'const int * ” 和 gcc 中的类似错误

当我将声明更改为:

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

或者

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

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

4

2 回答 2

8

的类型aint*[]; 你想要的类型是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**to的隐式转换int const *const *是合法的。(否则,您将需要一个const_cast地方来告诉编译器您知道自己在做什么,并且这不是真正的问题。)

于 2012-02-24T09:19:10.240 回答
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),但是对参数值具有常量性实际上对您可以调用的内容没有影响。


编辑: “但不是隐含地添加了 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 在他的回答中解释得更好。

于 2012-02-24T09:11:33.890 回答