3

I have in class County.h constructor:

struct Country {
    Country(double**, int);
};

and in main I have graph[Size][Size] and I want to call the constructor for County.

int main() {
    double graph[Size][Size];
    Country c(graph, 0);
}

But its giving me error no matching function for call to ‘County::County(double [22][22], int)’

What I can do in order to solve this problem?

peterh
  • 9,698
  • 15
  • 68
  • 87
MaxDevelop
  • 567
  • 1
  • 3
  • 14

2 Answers2

4

double [Size][Size] and double** are not at all the same type. That is what your compiler doesn't like.

Change your constructor prototype or the way you declare your array. But you cannot directly cast an array of array to a pointer of pointer.

struct Country {
    Country(double[Size][Size], int);
};

OR:

int main() {
    double** graph = new (double*)[Size];
    for (int i = 0; i < Size; ++i) {
        graph[i] = new double[Size];
    }
    Country c(graph, 0);

    // Don't forget to delete your graph then.
}

Note that the first one requires that you would know the size before your code start its execution (storing Size in a macro for instance), but the second one is longer to code, and you will have to manipulate more RAM memory, that can lead to mistakes if you are not careful.

Aracthor
  • 5,277
  • 6
  • 27
  • 53
  • i think i created like your first solution but I didn't give Size – MaxDevelop May 05 '15 at 14:32
  • @Saif If in your Country.h, you coded your constructor taking a `double **` parameter, it's not at all like if you just didn't gave a Size: It is a different variable type. A valid constructor here would be taking a `double [x][x]` with `x` in a Macro. – Aracthor May 05 '15 at 14:34
1

An alternative is to declare your constructor as a template and pass the array by (const) reference,

struct Country {
    template<size_t N>
    Country(double /*const*/ (&arr)[N][N], int);
};

In this way, the template will deduce the size of the array directly. Of course, the downside is that the above won't work with double pointers. The upside is that the compiler will strongly check the type and your program won't even compile if the array is not made of doubles (no conversions are being performed at type deduction) or if it is not square.

vsoftco
  • 52,188
  • 7
  • 109
  • 221
  • 1
    The trouble with this approach is, that it links pretty much everything that has to handle this array together into one compilation unit. But, yes, it seems to be the best that C++ can do. In that regard it's clearly inferior to C... – cmaster - reinstate monica May 05 '15 at 14:47
  • @cmaster I guess that's the price to pay for enforcing type safety. – vsoftco May 05 '15 at 14:48
  • @cmaster have to say I'm not very familiar with pure `C`. So you'd write the such function like `void f(int m, int n, int x[m][n]){}` and pass the dimensions? (I think you need at least to pass the dimensions). The problem is that it will allow passing arrays of different sizes and types (at least on my machine `gcc` only spits an warning). – vsoftco May 05 '15 at 15:00
  • Yes, that is the basic idea. Unfortunately, I have to realize that you are right, `gcc` does not check the types. I would guess that that's a deficiency of `gcc`, not of the standard, but I may be wrong. Theoretically, it would be possible to do all the required type-checking (you don't need to know what value an array size has to assert that two array types derived from the same variables are the same), but it does add quite a bit of compiler complexity, and VLAs are not the most heavily used feature. – cmaster - reinstate monica May 05 '15 at 15:17