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

时间:2014-03-26 16:25:38

标签: c++ c pointers arguments

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

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

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

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

稍后使用sort方法:

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

我收到编译器错误,“2个重载都不能转换所有参数类型。”

不是类型double *,指向double的指针,与double **没有根本不同,指向double的指针?

编译器如何不清楚?

4 个答案:

答案 0 :(得分:4)

您收到错误是因为*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) {
    //...
}

答案 1 :(得分:3)

您的变量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表示不应修改输入参数。

答案 2 :(得分:2)

非常明确,但*test test类型double *时的test[0]double相同,即它是&test { {1}}而不是指针。

也许你的意思是{{1}}取指针的地址。

答案 3 :(得分:1)

*test直接转到存储在该内存地址中的值。因此,它转到存储在地址double中的test,这是一个指向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.