为什么编译器不能区分double**和double*

Why can the compiler not differentiate between double** and double*

本文关键字:double 编译器 不能区 为什么      更新时间:2023-10-16

我创建了两个例程,一个用于对向量进行就地排序:

void Sort(double** vector, unsigned int vectorLength) {
    //...
}

和一个返回带有排序结果的新数组:

double* Sort(double* vector, unsigned int vectorLength) {
    //...
}

后面使用sort方法:

double* test = new double[5];
//...
Sort(*test, 5);

我收到编译器错误,'没有一个重载可以转换所有的参数类型。'

类型不是double*(指向double类型的指针)与double**(指向double类型的指针)没有本质上的区别吗?

为什么这对编译器不清楚?

您得到错误,因为*test表达式既不是double*也不是double** -它是double,没有星号。

传递test而不解引用它是可以工作的:

double* sorted = Sort(test, 5); // Invokes the second overload

注意,即使传递指针,也可以就地排序。使用一个重载,需要一个人工的&,工作,但它使你的API反直觉。

更好的方法是定义一个具有相同参数集但名称不同的方法,例如

double* Sort(double* vector, size_t vectorLength) {
    //...
}
void SortInPlace(double* vector, size_t vectorLength) {
    //...
}

您的变量test具有类型double*,因此*double具有类型double。这意味着您正在尝试传递既不匹配double*也不匹配double**double

一种可能是您实际上想要创建原始数组的排序副本:

double* sorted = Sort(test, 5);

但我宁愿假设,因为你对Sort的调用忽略了返回值,你的意思是传递&test来就地排序。

Sort(&test, 5);

然而,这本身就表明你的界面设计得很糟糕。如果希望函数修改test,则传递&test。但你没有。您希望该函数修改test所引用的数组。您的就地排序函数可以而且应该通过传递一个类型为double*的参数来实现。

我认为你在这里滥用了函数重载。我建议您选择一种不同的设计。我会使用不同名称的函数。

其他注释:

  1. 使用size_t作为数组长度
  2. 使用const表示输入参数不允许修改。

这是非常清楚的,但表达式*test时,test有类型double *是相同的test[0],即它是一个double,而不是一个指针,在所有

也许你想让&test获取指针的地址

*test直接访问存储在该内存地址中的值。因此,它会转到地址test中的double,这是一个指向double的指针。

所以,你传递的是一个double值,而不是一个指针。

你的作品可以和下面两个中的任何一个一起使用:

Sort(test, 5); // Passes a pointer to double.

Sort(&test, 5); // Gives you the address of test. Passes a pointer to a pointer to double.