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

C++ 为什么编译器不能区分double**和double*,c++,c,pointers,arguments,C++,C,Pointers,Arguments,我创建了两个例程,一个用于对向量进行适当排序: void Sort(double** vector, unsigned int vectorLength) { //... } 以及返回带有排序结果的新数组的: double* Sort(double* vector, unsigned int vectorLength) { //... } 稍后使用排序方法: double* test = new double[5]; //... Sort(*test, 5); 我收到编译器

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

void Sort(double** vector, unsigned int vectorLength) {
    //...
}
以及返回带有排序结果的新数组的:

double* Sort(double* vector, unsigned int vectorLength) {
    //...
}
稍后使用排序方法:

double* test = new double[5];
//...
Sort(*test, 5);
我收到编译器错误“2个重载都不能转换所有参数类型。”

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


编译器怎么会不清楚呢?

这很清楚,但是
test
类型为
double*
时的表达式
*test
test[0]
相同,即它是
double
而不是指针


也许您的意思是
&test
获取指针的地址。

您的变量
test
具有类型
double*
,因此
*double
具有类型
double
。这意味着您正试图通过既不匹配
double*
也不匹配
double**
double

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

double* sorted = Sort(test, 5);
但我认为,由于对
排序
的调用忽略了返回值,因此您希望通过
测试
进行适当排序

Sort(&test, 5);
然而,这本身就表明您的界面设计糟糕。如果希望函数修改
测试
,您将通过
测试。但你没有。您希望函数修改
test
引用的数组。就地排序功能可以也应该通过传递类型为
double*
的参数来实现

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

其他一些评论:

  • 对数组长度使用
    size\t
  • 使用
    const
    指示不应修改输入参数

  • 出现错误是因为
    *test
    表达式既不是
    double*
    也不是
    double**
    -它是
    double
    ,没有星号

    通过
    测试
    而不取消引用本可以:

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

    因此,您传递的是一个
    double
    值,而不是指针

    您的工作将与以下两项中的任何一项配合使用:

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


    编译器不是一个神奇的实体。它完全按照你说的做,在这种情况下,你说的是不正确的。啊,新手错误。我觉得这个问题现在已经没有什么价值了……对其他人来说没有价值,但对你来说有价值。给你的第一个教训是,你不应该以这种方式滥用重载,但那是毫无意义的。这是一个重载,它不会修改传递的数据,并返回一个新数组。所以你的代码泄漏了。@DavidHeffernan你是对的,OP说“返回一个带有排序结果的新数组”!谢谢你指出这一点!谢谢David,引用与取消引用正是问题所在。然后我明白了为什么你说接口设计得很糟糕,实现的第一行是获取内部指针并处理它。但是你可以帮助我。我倾向于设置这些低级操作符的方式是,让一个就地操作符和一个返回值操作符与调用就地实现的返回值版本并排。这是在.net中。什么是一个好的C++,这个结构仍然可以使用重载,而不需要丑陋的函数名?另外,使用SigeZt有什么好处?我以前见过,但坦率地说,这看起来像是过去的遗留问题,所以我避免了它。在我继续之前,我想知道这是否有必要。您是否知道
    std::vector
    是适合您的问题的标准容器。相当于C#中的
    List
    。David,我正在使用一个既使用向量又使用数组的现有代码库,因此在不进行完全重构的情况下,我确实需要在向量的舒适度以下工作。size#t是用于测量长度的类型。它在C++中到处都有使用。
    Sort(&test, 5); // Gives you the address of test. Passes a pointer to a pointer to double.