1

How can I set a pointer in a class to an external static data structure?

struct Str {
    double **matr;   // which type should matr be?
    int nx, ny;

    template<size_t rows, size_t cols>
    void Init(double(&m)[rows][cols], int sx, int sy) {
        matr = m;     // <-- error
        nx = sx; ny = sy;
    }
};
...
static double M[3][5] = { { 0.0, 1.0, 2.0, 3.0, 4.0 },
                          { 0.1, 1.1, 2.1, 3.1, 4.1 },
                          { 0.2, 1.2, 2.2, 3.2, 4.2 } };
Str s;
s.Init(M, 3, 5);

With this code, I get the following compile time error message (Visual C++ 2008/2012):

1> error C2440: '=' : cannot convert from 'double [3][5]' to 'double **'
1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1> see reference to function template instantiation 'void S::Init4<3,5>(double (&)[3][5],int,int)' being compiled

5
  • Your over-use of M is likely to get confusing - you have M the static array of doubles and M the template parameter for the void Str::Init() function. Which one are you intending double (*m)[M] to refer to? I think you want your mattr to be simply double *mattr, or maybe the uglier double (*mattr)[5]... Commented May 23, 2014 at 15:10
  • what does double(*m)[S] mean? Is it an array of function pointers? Commented May 23, 2014 at 15:16
  • @Cool_Coder - It was a 2D array. Now it should be clearer. Commented May 23, 2014 at 15:17
  • ok so whats the problem? is it not compiling? Commented May 23, 2014 at 15:21
  • @Cool_Coder - I added the error I get in the message. Commented May 23, 2014 at 15:28

2 Answers 2

1

The problem is that a 2D array of double is not an array of pointers, it's just a single pointer to the first element of the 2D array that is represented by several contiguous rows of doubles in memory.

Since your struct has the fields nx/ny, you could just convert the array to a simple pointer and then use nx/ny to access it, i.e.:

struct Str {
    double *matr;
    int nx, ny;

    void Init(double* m, int sx, int sy) {
        matr = m;
        nx = sx; ny = sy;
    }
};

static double M[3][5] = { { 0.0, 1.0, 2.0, 3.0, 4.0 },
                          { 0.1, 1.1, 2.1, 3.1, 4.1 },
                          { 0.2, 1.2, 2.2, 3.2, 4.2 } };

int main() {
    Str s;
    s.Init(M[0], 3, 5);
    return 0;
}

You would then have to use nx/ny to access the array, e.g. here is a function that could be added to struct Str that prints the array:

#include <iostream>

void print() {
    for (int i = 0; i < nx; i++) {
        for (int j = 0; j < ny; j++) {
            std::cout << matr[i*ny+j] << " ";
        }
        std::cout << std::endl;
    }
}

Another (arguably nicer) solution would be to add template parameters to struct Str that replace nx/ny, then the matr member could have a type that contains the dimensions.

Sign up to request clarification or add additional context in comments.

1 Comment

If I use template parameters in the structure, I must specify the dimensions when I define the object. Can I use templates on the member function to have the option to resize the object later? Reference: user2079303's answer.
1

So, you want to have a pointer to a 2D array. Str must be a template, because the type of it's member matr depends on the dimensions of that array.

template<int rows, int cols>
struct Str {
    double (*matr)[rows][cols];

    void Init(double(&m)[rows][cols]) {
        matr = &m;
    }
};

Str<3, 5> s;
s.Init(M);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.