Can a class have a non-static const array as a data member?

P

partha.p.das

Here is my class:

class MyClass {
public:

MyClass();

~MyClass();

private:

// non-static const array as a data member
const int memArr_[5];
};

Is such a class (with non-static const array as a data member) valid?
Since I cannot see why it may not be valid, I presume that it is valid.

Therefore when an object of MyClass is constructed, memArr_[5], being a
const embedded object, will need to get initialized in the constructor.
My problems start here as I cannot write a constructor that has the
right initializer for the above array. Every attempt gives a
compilation error (the errors reported below are from VC++ 7.1 - but
I get similar errors in VC++ 6.0 and GCC 3.2.x on Linux).

Attempt 1:
==========

MyClass::MyClass():
memArr_(0, 1, 2, 3, 4)
// error C2536: 'MyClass::MyClass::c_memArr_' :
// cannot specify explicit initializer for arrays
{ }


Attempt 2:
==========

MyClass::MyClass():
memArr_({0, 1, 2, 3, 4})
// error C2958: the left parenthesis '('
// found at '...\myclass.hxx(17)' was
// not matched correctly
{ }


Attempt 3:
==========

MyClass::MyClass()
// error C2439: 'MyClass::c_memArr_' :
// member could not be initialized
{ }


Can anyone tell me if I am missing something here and show me how to
write the initializer correctly? Or if this is wrong according to C++
standard and why (I cannot convince myself why should this be wrong)?
Or is this a compiler limitation?
 
M

Mark P

Here is my class:

class MyClass {
public:

MyClass();

~MyClass();

private:

// non-static const array as a data member
const int memArr_[5];
};

Is such a class (with non-static const array as a data member) valid?
Since I cannot see why it may not be valid, I presume that it is valid.

Therefore when an object of MyClass is constructed, memArr_[5], being a
const embedded object, will need to get initialized in the constructor.
My problems start here as I cannot write a constructor that has the
right initializer for the above array. Every attempt gives a
compilation error (the errors reported below are from VC++ 7.1 - but
I get similar errors in VC++ 6.0 and GCC 3.2.x on Linux).

My understanding is that there's nothing which prohibits you from having
such a member however, since it must be initialized in the ctor, its
usefulness is quite limited. As you discovered, lists (with or without
brackets) are not valid initializers. The only valid initialization I
know of is memArr_() which will default initialize all of the array
elements (0 for built-in types). Or you can not explicitly initialize
it and take whatever junk the compiler gives you.

Mark
 
M

Marcus Kwok

Mark P said:
The only valid initialization I
know of is memArr_() which will default initialize all of the array
elements (0 for built-in types).

However, be aware that at least one popular compiler (VS .NET 2003, aka
VC++ 7.1) does not do this correctly:

http://groups.google.com/group/comp.lang.c++/browse_frm/thread/602375401ad4b39a/dab44a8b786b6a79

and read the response by Dietmar Kuehl also.


However, they did fix it in the new version (VS .NET 2005, aka VC++
8.0), and Patrick Kowalzick has also posted a work-around for the older
version:

http://groups.google.com/group/micr..._frm/thread/b5d0dbefaa1c4286/b3a339bdd2c2aa6e
 
K

Kaz Kylheku

Here is my class:

class MyClass {
public:

MyClass();

~MyClass();

private:

// non-static const array as a data member
const int memArr_[5];
};

Is such a class (with non-static const array as a data member) valid?
Since I cannot see why it may not be valid, I presume that it is valid.

It's valid. Consider that the elements could be of class type. In that
case, they will be nicely initialized by their default constructors.

Also, an array could be wrapped in a struct. The const qualifier could
be put on the struct member instead of the array, like this:

const struct Foo {
int array[5];
} s; // s is the non-static member of the class

So now you can initialize the thing in the constructor, because what
you are initializing is a struct object, and not an array member.

MyClass::MyClass(Foo init)
: s(init)
{
}

Or:

// static member function
MyClass::Foo MyClass::makeFooStruct( ... args ...)
{
}

MyClass::MyClass()
: s(makeFooStruct(... args ...))
{
}

I.e. you write some function that constructs a Foo according to some
parameters, and then call it in your constructor's initializing
expression.
 
M

Mark P

Marcus said:
However, be aware that at least one popular compiler (VS .NET 2003, aka
VC++ 7.1) does not do this correctly:

A good point, and in fact, not the only compiler with this defect. I've
seen problems with a version of the Sun CC compiler too.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,682
Members
48,796
Latest member
Greg L.

Latest Threads

Top