472,980 Members | 1,763 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,980 software developers and data experts.

Initializing multi-dimensional array in constructor

I'm having a ton of trouble initializing a multi-dimensional array
inside a constructor, largely because I don't know the size of the
array until runtime. I have a class that looks like this:

class MyClass
{
public:
const int size;
MyClass( const int );
};

MyClass::MyClass( const int s )
: size( s )
{
int (*arrayPtr)[size][size] = new int[size][size][size];
}

When I compile this with g++ (actually, Apple's version of g++, in case
that matters), I get the following error:
myclass.cpp : In constructor 'MyClass::MyClass(int)':
myclass.cpp.8: error: 'MyClass::size' cannot appear in a
constant-expression
myclass.cpp.8: error: 'MyClass::size' cannot appear in a
constant-expression

Can anyone explain why I'm getting this error message, especially since
size is declared const, and also can anyone help me out with what to do
about it? Thanks.

--Jay

Jul 24 '06 #1
4 4340
ja*******@gmail.com wrote:
I'm having a ton of trouble initializing a multi-dimensional array
inside a constructor, largely because I don't know the size of the
array until runtime. I have a class that looks like this:

class MyClass
{
public:
const int size;
MyClass( const int );
};

MyClass::MyClass( const int s )
: size( s )
{
int (*arrayPtr)[size][size] = new int[size][size][size];
}

When I compile this with g++ (actually, Apple's version of g++, in
case that matters), I get the following error:
myclass.cpp : In constructor 'MyClass::MyClass(int)':
myclass.cpp.8: error: 'MyClass::size' cannot appear in a
constant-expression
myclass.cpp.8: error: 'MyClass::size' cannot appear in a
constant-expression

Can anyone explain why I'm getting this error message, especially
since size is declared const, and also can anyone help me out with
what to do about it? Thanks.
Please see the FAQ. Creation of multidimensional dynamic arrays is
actually covered in it.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jul 24 '06 #2
Jay Harris posted:

int (*arrayPtr)[size][size] = new int[size][size][size];

You're going to need to employ more devious tactics, something like:

(I've written this hastily in the last half hour, so expect bugs.)
#include <cassert>

template<class T>
class Accessor2D {
protected:

T *const p;
unsigned const d2;

public:

Accessor2D(T *const parg,unsigned const arg2) : p(parg), d2(arg2)
{
assert(parg);
assert(arg2);
}

T *operator[](unsigned const arg2)
{
assert(arg2);

return p + (arg2 * d2);
}
};
template<class T>
class Accessor3D {
protected:

T *const p;
unsigned const d2;
unsigned const d3;

public:

Accessor3D(T *const parg,unsigned const arg2, unsigned const arg3)
: p(parg), d2(arg2), d3(arg3)
{
assert(parg);
assert(arg2);
assert(arg3);
}
Accessor2D<Toperator[](unsigned const arg1)
{
assert(arg1);

return Accessor2D<T>( p + (arg1 * d2 * d3), d3 );
}
};
/* Now here comes your class */
class MyClass {
public:
unsigned const size;
MyClass(unsigned const);
};

MyClass::MyClass(unsigned const s) : size(s)
{
Accessor3D<intarr(new int[size*size*size],size,size);

arr[0][0][0] = 5;

arr[0][1][2] = 7;
}

int main()
{
MyClass obj(7);
}

--

Frederick Gotham
Jul 24 '06 #3
ja*******@gmail.com wrote:
I'm having a ton of trouble initializing a multi-dimensional array
inside a constructor, largely because I don't know the size of the
array until runtime. I have a class that looks like this:
"Size" portion of array types in C++ must be a so called 'integral constant
expression' (ICE). The exact definition of ICE can be found in the language
specification, but the idea is that the size must be known at compile time.
Non-static class data members cannot be used in ICEs. This is what makes the
compiler to complain.

Since in your case array sizes are only known at run-time, there's no way to
achieve what you want with array type or type derived from array type (as the
'int (*)[size][size]' you are trying to use). There are different ways to solve
the problem:

1. Use a 1D array of size 'size * size * size' and simulate a 3D access by
manually transforming the 3D indices into the corresponding the 1D index:

[x][y][z] - [x * size * size + y * size + z]

(that's, BTW, how built-in arrays work in C/C++)

2. Use the well-known array-of-pointers idiom:

int*** arrayPtr = new int**[size];
// Then for each i
arrayPtr[i] = new int*[size];
// Then for each i, j
arrayPtr[i][j] = new int[size];

(the above is just an illustration of the idea; the actual implementation can be
done in a neater way).

3. (Might make the most sense out of three) Use
'std::vector<std::vector<std::vector<int >'.
class MyClass
{
public:
const int size;
MyClass( const int );
};

MyClass::MyClass( const int s )
: size( s )
{
int (*arrayPtr)[size][size] = new int[size][size][size];
}

When I compile this with g++ (actually, Apple's version of g++, in case
that matters), I get the following error:
myclass.cpp : In constructor 'MyClass::MyClass(int)':
myclass.cpp.8: error: 'MyClass::size' cannot appear in a
constant-expression
myclass.cpp.8: error: 'MyClass::size' cannot appear in a
constant-expression
--
Best regards,
Andrey Tarasevich
Jul 24 '06 #4
Thanks. Option 1 seemed the simplest, so I went with it.

Andrey Tarasevich wrote:
ja*******@gmail.com wrote:
I'm having a ton of trouble initializing a multi-dimensional array
inside a constructor, largely because I don't know the size of the
array until runtime. I have a class that looks like this:

"Size" portion of array types in C++ must be a so called 'integral constant
expression' (ICE). The exact definition of ICE can be found in the language
specification, but the idea is that the size must be known at compile time.
Non-static class data members cannot be used in ICEs. This is what makes the
compiler to complain.

Since in your case array sizes are only known at run-time, there's no way to
achieve what you want with array type or type derived from array type (as the
'int (*)[size][size]' you are trying to use). There are different ways to solve
the problem:

1. Use a 1D array of size 'size * size * size' and simulate a 3D access by
manually transforming the 3D indices into the corresponding the 1D index:

[x][y][z] - [x * size * size + y * size + z]

(that's, BTW, how built-in arrays work in C/C++)

2. Use the well-known array-of-pointers idiom:

int*** arrayPtr = new int**[size];
// Then for each i
arrayPtr[i] = new int*[size];
// Then for each i, j
arrayPtr[i][j] = new int[size];

(the above is just an illustration of the idea; the actual implementation can be
done in a neater way).

3. (Might make the most sense out of three) Use
'std::vector<std::vector<std::vector<int >'.
class MyClass
{
public:
const int size;
MyClass( const int );
};

MyClass::MyClass( const int s )
: size( s )
{
int (*arrayPtr)[size][size] = new int[size][size][size];
}

When I compile this with g++ (actually, Apple's version of g++, in case
that matters), I get the following error:
myclass.cpp : In constructor 'MyClass::MyClass(int)':
myclass.cpp.8: error: 'MyClass::size' cannot appear in a
constant-expression
myclass.cpp.8: error: 'MyClass::size' cannot appear in a
constant-expression

--
Best regards,
Andrey Tarasevich
Jul 26 '06 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

50
by: Dan Perl | last post by:
There is something with initializing mutable class attributes that I am struggling with. I'll use an example to explain: class Father: attr1=None # this is OK attr2= # this is wrong...
14
by: Avi Uziel | last post by:
Hi All, I'm writing a Windows DLL which contain some utility classes. One of my classes is Singleton, therefore contain some static members. I'm using VC6 and linking to the DLL statically. ...
12
by: * ProteanThread * | last post by:
but depends upon the clique: ...
6
by: cody | last post by:
What are multi file assemblies good for? What are the advantages of using multiple assemblies (A.DLL+B.DLL) vs. a single multi file assembly (A.DLL+A.NETMODULE)?
4
by: mimmo | last post by:
Hi! I should convert the accented letters of a string in the correspondent letters not accented. But when I compile with -Wall it give me: warning: multi-character character constant Do the...
5
by: bobwansink | last post by:
Hi, I'm relatively new to programming and I would like to create a C++ multi user program. It's for a project for school. This means I will have to write a paper about the theory too. Does anyone...
8
by: SM | last post by:
I've always wonder if there is diference when declaring and initializing a varible inside/outside a loop. What's a better practice? Declaring and initializing variables inside a loop routine,...
0
by: Sabri.Pllana | last post by:
We apologize if you receive multiple copies of this call for papers. *********************************************************************** 2008 International Workshop on Multi-Core Computing...
1
by: mknoll217 | last post by:
I am recieving this error from my code: The multi-part identifier "PAR.UniqueID" could not be bound. The multi-part identifier "Salary.UniqueID" could not be bound. The multi-part identifier...
38
by: junky_fellow | last post by:
Guys, I was just looking at some code where to initialize an integer with all F's following statement is used; unsigned int i = -1; I want to know if this is the right way of doing the...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
0
tracyyun
by: tracyyun | last post by:
Hello everyone, I have a question and would like some advice on network connectivity. I have one computer connected to my router via WiFi, but I have two other computers that I want to be able to...
3
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be using a very simple database which has Form (clsForm) & Report (clsReport) classes that simply handle making the calling Form invisible until the Form, or all...
1
by: Teri B | last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course. 0ne-to-many. One course many roles. Then I created a report based on the Course form and...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 1 Nov 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM) Please note that the UK and Europe revert to winter time on...
3
by: nia12 | last post by:
Hi there, I am very new to Access so apologies if any of this is obvious/not clear. I am creating a data collection tool for health care employees to complete. It consists of a number of...
0
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be focusing on the Report (clsReport) class. This simply handles making the calling Form invisible until all of the Reports opened by it have been closed, when it...
0
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...
4
by: GKJR | last post by:
Does anyone have a recommendation to build a standalone application to replace an Access database? I have my bookkeeping software I developed in Access that I would like to make available to other...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.