2

The following is the method signature in a class.

virtual void evaluate(const double *var, double *obj, double *constr) const = 0;

virtual void evaluate(unsigned int numPoints, const double **var, double **obj, double **constr) const {
    //do something
}

Here is the declaration of arguments

unsigned int size;
double **var = new double*[size];
double **obj = new double*[size];
double **constr = new double*[size];

Here is the method call.

evaluator.evaluate(size, var, obj, constr);

I get the following compiler error.

foo.cpp: In member function âvoid foo::evaluatePopulation(std::vector<Individual, std::allocator<Individual> >&, unsigned int, bool)â:
foo.cpp:347: error: no matching function for call to foo::evaluate(unsigned int&, double**&, double**&, double**&) constâ
foo.h:35: note: candidates are: virtual void foo::evaluate(const double*, double*, double*) const
foo.h:43: note:                 virtual void foo::evaluate(unsigned int, const double**, double**, double**) const <near match>

foo are class names. I am using double pointers (two asterisks). How do I resolve this error?

Sander De Dycker
  • 16,053
  • 1
  • 35
  • 40
Santosh Tiwari
  • 1,167
  • 2
  • 14
  • 26
  • The signature you show for `evaluate` doesn't match the one in the error message. – simonc Sep 05 '13 at 16:05
  • Well the call you are making takes a ptrptr, which you could get by taking the address of var, obj, ect. However, your declaration of constr makes no sense (the compiler should say you can't cast double* to double** or something like that) – IdeaHat Sep 05 '13 at 16:06
  • Someone is editing the code in a way that doesn't reflect the original problem anymore. – Nikos C. Sep 05 '13 at 16:08
  • 1
    @NikosC. P0W edited the code, reporting "OP has problem with **, SO eats up *" in an answer that has since been deleted. I had rolled back to the original question but reinstated the edits based on this comment. – simonc Sep 05 '13 at 16:10
  • @NikosC I just added ` ` ` ` for his variables I saw OP already used those – P0W Sep 05 '13 at 16:12
  • @SantoshTiwari is this your original code, you may wish to change it. SO uses two asterisk to make text **bold** – P0W Sep 05 '13 at 16:15
  • 1
    If this is the actual code, and the actual compiler error message, the error message is extremely misleading. The problem is clearly that he's trying to pass a `double**` to a `double const**`, and there's no conversion which will do that. (Perhaps the function should be delcared to take a `double const* const*`?) – James Kanze Sep 05 '13 at 16:15
  • 2
    @simonc : now everything matches up – Sander De Dycker Sep 05 '13 at 16:22
  • You may avoid all these errors by using std::vector. – Jarod42 Sep 05 '13 at 16:38
  • Thanks guys for fixing up my post. I generally use vector (actually valarray) but, I am using raw arrays so as to easily interface with C/fortran if necessary. – Santosh Tiwari Sep 05 '13 at 17:59

1 Answers1

3

In your second signature, the type of the second formal parameter, var, is const double**. The actual argument, constr, is, hovewer of type double** which cannot be implicitly converted to the former type.

Example

#include <stdio.h>

void fn(const int** pp)
{
    printf("%p : %p : %d", pp, *pp, **pp);
}

int main()
{
    int n = 1;
    int *p = &n;
    fn(&p); // ERROR. see below
    return 0;
}

The error reported is accurate:

main.c:17:8: Passing 'int **' to parameter of type 'const int **' discards qualifiers in nested pointer types.

Pete Becker
  • 74,985
  • 8
  • 76
  • 165
ach
  • 2,314
  • 1
  • 13
  • 23
  • true, and not immediately obvious (as most `T` can implicitly become `const T`). But, with pointers, `double**` can implicitly become `const double * const * const`. Yes, it's a lot of const, but it should work. – Tim Sep 05 '13 at 16:23
  • 1
    @Tim: actually `double **` can only implicitly become `double * const * const`. That's because you can only implicitly convert `T *` to `const T *` or `T &` to `const T&` or initialize a `const T` with a `T`. That's it -- no other implicit const stuff happens. – Chris Dodd Sep 05 '13 at 17:01
  • Thanks. The error is resolved after changing the signature to "const double* const *var". I should have been specifying it correctly to prevent "var" from getting modified. – Santosh Tiwari Sep 05 '13 at 19:56
  • 1
    @Chris Dodd: That is actually incorrect. In C++, `T **` is implicitly convertible to `const T *const *` (but, of course, not to `const T **`). A similar rule works for references: an lvalue of type `T *` can be used to initialize a reference of type `const T *const &`, but not of type `const T *&`. (See also http://stackoverflow.com/questions/5248571/is-there-const-in-c/5249001#5249001) – AnT stands with Russia Sep 05 '13 at 20:19