Click here to Skip to main content
14,699,489 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I everyone,

Constant arrays must be initialized at declaration. But what if the array is declared in a class? I've been searching but didn't find a solution so far, does anybody know?
Example:
template <class t=""> class Foo
{
const T vec[10];
};

regards to all.
Posted
Updated 6-Jun-12 10:29am
v2

1 solution

In C++98 you can't. But if you dig into the murky past of C++ and it's C heritage then you can. The thing that gets around this is the fact that if an array is part of another structure or class it gets copied along with everything else when the structure is copied. So if anyone tells you that you can't return an array by value, tell them of course you can:
struct B
{
    int data[15];
};

B grab_a_B()
{
    B b;
    b.data[0] = 125;
    // and so on...
    return b;
};
So how does this help you? Well instead of using a const array in your class, use a const instance of a structure instead:
class A
{
    public:
        A( const B &b ) : b_( b ) {}

    private:
        const B b_;
};
Initialise a B, feed it to an A and snip, snip, Bob's yer aunty.

In C++11 there is a feature (uniform initialisation) that you can use to do the same thing. So you can do something like:
class A
{
    public:
        A(): arr( {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15} ) {}
    private:
        const int arr[ 15 ];
};
although the syntax is from memory. Visual Studio up 'til 2010 doesn't support this, I'm not sure about gcc whether gcc does either.
   
Comments
AndreFratelli 6-Jun-12 13:02pm
   
that is what I call an awesome answer! =)

I didn't take exactly the same approach, though. But the idea to pass an encapsulated array to the constructor gave me an idea. So I did this:

<pre>
// "const_array" and "array" are inner classes, size_type and T are defined in the parent class
template < size_type _Capacity > class const_array
{
public:
const T& operator[](size_type index) const { ... }
protected:
T items[_Capacity];
};

template < size_type _Capacity > class array
: public const_array<_Capacity>
{
public:
T& operator[](size_type index) { /* not const */ }
};
</pre>

Now, to initialize first construct an "array" and pass it to "const_array". Worked like a charm =)

What do you think?

Thank you!
Aescleal 7-Jun-12 5:50am
   
It looks like it would work fairly well. The only point I'd make is that protected members of a class generally set alarm bells off. Protected is for implementation inheritance which has the problem of tightly coupling classes together. So be careful if you end up with inheritance hierarchies deeper than one or two levels - they can bite. My career still has the teeth marks from some attempts at using implementation inheritance.

One thing I didn't mentioned yesterday and probably should have - you could have done something similar with a std::vector. Initialise one outside of the class and hold it as a const member. However if you want the memory for the array to be part of the object (for whatever reason, I don't want to know, it might be perverse and horrible!) then you have to use a proxy.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900