std::vector
uses the heap. Geez, what a waste that would be just for the sake of a const
sanity-check. The point of std::vector
is dynamic growth at run-time, not any old syntax checking that should be done at compile-time. If you're not going to grow then create a class to wrap a normal array.
#include <stdio.h>
template <class Type, size_t MaxLength>
class ConstFixedSizeArrayFiller {
private:
size_t length;
public:
ConstFixedSizeArrayFiller() : length(0) {
}
virtual ~ConstFixedSizeArrayFiller() {
}
virtual void Fill(Type *array) = 0;
protected:
void add_element(Type *array, const Type & element)
{
if(length >= MaxLength) {
// todo: throw more appropriate out-of-bounds exception
throw 0;
}
array[length] = element;
length++;
}
};
template <class Type, size_t Length>
class ConstFixedSizeArray {
private:
Type array[Length];
public:
explicit ConstFixedSizeArray(
ConstFixedSizeArrayFiller<Type, Length> & filler
) {
filler.Fill(array);
}
const Type *Array() const {
return array;
}
size_t ArrayLength() const {
return Length;
}
};
class a {
private:
class b_filler : public ConstFixedSizeArrayFiller<int, 2> {
public:
virtual ~b_filler() {
}
virtual void Fill(int *array) {
add_element(array, 87);
add_element(array, 96);
}
};
const ConstFixedSizeArray<int, 2> b;
public:
a(void) : b(b_filler()) {
}
void print_items() {
size_t i;
for(i = 0; i < b.ArrayLength(); i++)
{
printf("%d\n", b.Array()[i]);
}
}
};
int main()
{
a x;
x.print_items();
return 0;
}
ConstFixedSizeArrayFiller
and ConstFixedSizeArray
are reusable.
The first allows run-time bounds checking while initializing the array (same as a vector might), which can later become const
after this initialization.
The second allows the array to be allocated inside another object, which could be on the heap or simply the stack if that's where the object is. There's no waste of time allocating from the heap. It also performs compile-time const checking on the array.
b_filler
is a tiny private class to provide the initialization values. The size of the array is checked at compile-time with the template arguments, so there's no chance of going out of bounds.
I'm sure there are more exotic ways to modify this. This is an initial stab. I think you can pretty much make up for any of the compiler's shortcoming with classes.