9

値の数を表す要素を持つ列挙型の値によってインデックスが付けられたグローバル配列があります。配列は、残念ながら 0 ではない特別な値で初期化する必要があります。

enum {
  A, B, C, COUNT
};

extern const int arr[COUNT];

.cpp ファイルの場合:

const int arr[COUNT] = { -1, -1, -1 };

列挙型はときどき変更されます: 新しい値が追加され、いくつかは削除されます。修正したばかりのコードのエラーは、初期化値の数が不十分であり、配列の残りの部分がゼロで初期化されていました。この種のエラーに対する保護策を講じたいと思います。

arr問題は、 が特別な値 (例では the ) で常に完全に初期化されることを保証するか-1、開発者の注意を引くためにコンパイルを中断して、配列を手動で更新できるようにすることです。

最近の C++ 標準は利用できません (古い ms コンパイラと独自のジャンク)。テンプレートはある程度使用できます。STL と Boost は強く禁止されています (質問しないでください) が、必要な部分をコピーしたり再実装したりすることは気にしません。

それが不可能であることが判明した場合は、特別な値を 0 に変更することを検討する必要がありますが、それは避けたいと思います: 特別な値 ( -1) は少し特殊すぎて、コードの残りの部分で暗黙的にエンコードされている可能性があります。 .

私は DSL とコード生成を避けたいと思います: プライマリ ビルド システムは ms windows のジャムであり、そこで生成されたものを取得することは主要な PITA です。

4

5 に答える 5

7

私が思いつく最善の解決策は、 に置き換えarr[COUNT]arr[]から、それをアサートするテンプレートを作成することsizeof(arr) / sizeof(int) == COUNTです。これは に初期化される-1ことを保証しませんが、正しい要素数で配列を明示的に初期化したことを保証します。

C++11static_assertや Boost のマクロ バージョンがあればさらに良いのですが、どちらも利用できない場合は、自分で何かを考え出す必要があります。

于 2013-06-05T19:11:54.273 に答える
5

かんたんだよ。

enum {
  A, B, C, COUNT
};
extern const int (&arr)[COUNT];

const int (&arr)[COUNT] = (int[]){ -1, -1, -1};

int main() {
   arr[C];
}

一見、これによりオーバーヘッドが発生しているように見えますが、よく調べると、コンパイラが気にする限り、同じ変数に対して2 つの名前が生成されるだけです。したがって、オーバーヘッドはありません。

ここで動作しています: http://ideone.com/Zg32zH、エラーの場合は次のようになります: http://ideone.com/yq5zt3

prog.cpp:6:27: エラー: タイプ 'const int [2]' の式からのタイプ 'const int (&)[3]' の参照の無効な初期化</p>

一部のコンパイラでは、一時的に名前を付ける必要がある場合があります

const int arr_init[] = { -1, -1, -1};
const int (&arr)[COUNT] = arr_init;

アップデート

=(int[]){-1,-1,-1}最初のバージョンはコンパイラの拡張機能であると聞いているので、2 番目の=arr_init;バージョンが優先されます。

于 2013-06-07T18:02:02.240 に答える
2

私自身の質問に答える: 配列に適切な量の初期化子を直接提供することは不可能に思えますが、適切な量の初期化子のリストをテストするのは本当に簡単です:

#define INITIALIZERS -1, -1, -1,
struct check {
  check() {
    const char arr[] = {INITIALIZERS};
    typedef char t[sizeof(arr) == COUNT ? 1: -1];
  }
};

const int arr[COUNT] = { INITIALIZERS };

変数配列を使用して値をカウントするというアイデアについて、@dauphic に感謝します。

于 2013-06-05T20:06:50.867 に答える