std::vector
使用堆。这只是为了进行 const
的检查而浪费掉的空间。 std::vector
的重点在于运行时的动态增长,而不是编译时应该完成的语法检查。 如果您不需要增长,请创建一个类来封装普通数组。
#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) {
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
和ConstFixedSizeArray
可重复使用。
第一个允许在初始化数组时进行运行时边界检查(与向量相同),这些数组在初始化之后可以变为const
。
第二个允许数组在另一个对象内部分配,该对象可以在堆上或仅仅在栈上。没有浪费时间从堆中分配。它还对数组进行编译时常量检查。
b_filler
是一个小的私有类,用于提供初始化值。通过模板参数,在编译时检查数组的大小,因此不会越界。
我相信还有更多奇特的方法可以修改它。这是最初的尝试。我认为你可以用类来弥补编译器的任何缺陷。
struct a {const int b[2]{2, 3};};
。仍然可以像这个答案所示的那样,在构造函数初始化列表中将数组初始化为不同的值。 - adentinger