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) {
// 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
再ConstFixedSizeArray
利用可能です。
1 つ目は、配列の初期化中に実行時の境界チェックを許可します (ベクトルと同じ)。これは、後でconst
この初期化の後に行うことができます。
2 つ目は、別のオブジェクト内に配列を割り当てることができます。これは、オブジェクトが存在する場合は、ヒープまたは単にスタック上にある可能性があります。ヒープから割り当てる時間の無駄はありません。また、配列に対してコンパイル時の const チェックも実行します。
b_filler
初期化値を提供する小さなプライベート クラスです。配列のサイズはコンパイル時にテンプレート引数でチェックされるため、範囲外になる可能性はありません。
これを変更するためのよりエキゾチックな方法があると確信しています。これが初刺です。クラスに関するコンパイラの欠点をほぼ補うことができると思います。