J Collins
J Collins

Reputation: 2170

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

I have created two routines, one to sort a vector in-place:

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

and one that returns a new array with the sorted result:

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

Later using the sort method:

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

I receive the compiler error that 'none of the 2 overloads could convert all the argument types.'

Is not the type double*, a pointer to a double, not fundamentally different to a double**, a pointer to a pointer to a double?

How is this not clear to the compiler?

Upvotes: 0

Views: 113

Answers (4)

David Heffernan
David Heffernan

Reputation: 612954

Your variable test has type double* and so *double has type double. Which means that you are attempting to pass double which matches neither double* nor double**.

One possibility is that you actually meant to create a sorted copy of the original array:

double* sorted = Sort(test, 5);

But I rather presume, since your call to Sort ignores the return value, that you meant to pass &test to sort in-place.

Sort(&test, 5);

However, that in itself indicates that your interface is badly designed. You would pass &test if you wanted the function to modify test. But you don't. You want the function to modify the array that test refers to. Your in-place sort function can, and should, be implemented by passing a parameter of type double*.

It is my opinion that you are abusing function overloading here. I would recommend that you choose a different design. I would use functions with different names.

Some other comments:

  1. Use size_t for array lengths.
  2. Use const to indicate that an input parameter shall not be modified.

Upvotes: 3

ArthurChamz
ArthurChamz

Reputation: 2049

*test goes directly to the value stored in that memory address. So, it goes to the double stored in the address test, which is a pointer to double.

So, you're passing a double value, not a pointer.

Your work would work with either of these two:

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

or

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

Upvotes: 1

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726559

You get the error because *test expression is neither double* nor double** - it's a double, with no asterisks.

Passing test without dereferencing it would have worked:

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

Note that you can sort in place even if you pass a pointer. Using an overload for this that requires an artificial &, works but it makes your API counter-intuitive.

A better approach would be defining a method with the same set of parameters, but a different name, for example

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

Upvotes: 4

unwind
unwind

Reputation: 399813

It's very clear, but the expression *test when test has the type double * is the same as test[0], i.e. it's a double and not a pointer at all.

Perhaps you meant &test to take the address of the pointer.

Upvotes: 2

Related Questions