2011-09-17 9 views
5

整数(または列挙)キーと文字列値を持つ巨大な辞書を使用する必要があります。しかしこれは完全に一定です。実行時に変更する方法はありません。既存の辞書構造を使用するのではなく、コンパイル時に辞書データを取り出すための方法(テンプレートなどの使用)がありますか?C++で巨大で定数の辞書に使用するデータ構造

+3

データはどこから来ますか?テンプレートは、たとえば、ファイルから読み取ることができません。だから答えは、おそらく、コンパイル時にこれを行うことはできません。 –

+1

@Oli:ファイルは常に#includeできます。 –

+0

コンパイルする前に、設定ファイルをC++ファイルに変換することはできません。自動コード生成によって問題が解決される可能性があります。 –

答えて

5

ClangとLLVMは、コード生成とプリプロセッサトリッキーの組み合わせを使用して、オブジェクトを含むテーブルを生成することで問題を解決しました。

自分の設定に応じて、どちらのステップもスキップできます。あなたが列挙型を生成することができ

// records.inc 
EXPAND_RECORD(Foo, "Foo", 4); 
EXPAND_RECORD(Bar, "Bar", 18); 
EXPAND_RECORD(Bar2, "Bar", 19); 

、:たとえば、クランとLLVMで

// records.h 
enum Record { 

#define EXPAND_RECORD(Name, String, Value) Name, 
#include "records.inc" 
#undef EXPAND_RECORD 

}; 

char const* getRecordName(Record r); 
int getRecordValue(Record r); 

// records.cpp 

char const* getRecordName(Record r) { 
    switch(r) { 
#define EXPAND_RECORD(Name, String, Value) case Name: return String; 
#include "records.inc" 
#undef EXPAND_RECORD 
    } 

    abort(); // unreachable, or you can return a "null" value 
} 

int getRecordValue(Record r) { 
    switch(r) { 
#define EXPAND_RECORD(Name, String, Value) case Name: return Value; 
#include "records.inc" 
#undef EXPAND_RECORD 
    } 

    abort(); // unreachable, or you can return a "null" value 
} 

を、コード生成相は、より快適な定義ファイルからの.incを生成するために使用されます。

これはかなりうまくいきますが、列挙型の変更によって完全な再コンパイルが行われることに注意してください。列挙型が内部で使用されていても外部に流出することのない「コードセット」アプローチに行きたいと思うかもしれませんし、安定した値(enumのもの)がクライアントに提供されます(unsigned)再コンパイルせずにライブラリ:彼らは安定している場合は問題はない古いコードを使用するように制限されます。

3

きっとあなたは、単にのようなヘッダファイルで、テンプレートパラメータで指定されたインデックス定数文字列に辞書を変換するためにsedを使用することができます。

template <int Index> struct Dictionary { static const char *entry; }; 

、フォームの多くの行を持つソースファイル:

template <> const char *Dictionary<5>::entry = "Entry for five"; 

一方、実際にメンテナンスの観点からこの作業を行いたいですか?変更されたすべての辞書エントリと膨大な実行可能ファイルサイズに対して再コンパイルが必要です。

+0

のようになります。* Bloated *:エントリはどこかにある必要があります。少なくともROMに入れておくと、プログラムのさまざまなインスタンス間で重複しないことを意味します(DLL )。 *再コンパイル*:あなたが適切なインターフェースを持っていなければ、問題になる可能性があります。 –

0

自動コード生成はどうですか?構成ファイルまたはデータベース、またはソースが何であれ、C++ヘッダーコードを生成します。それはこのような何かを見ることができる:

#define MYCONST_1 "#00ff00" 
#define MYCONST_10 "My other configuration string" 

あなたは、単純なbashスクリプトまたはルビー/ pythonので変換を行うことができます(またはC++あなたはマゾであれば)、それはあなたの設定ファイルの複雑さに依存します。

次に、設定ファイルが変更されたときに自動的にヘッダファイルを作成するいくつかのmakeルールを作成します。

+0

私は今までコメントしていないうちにいつも私を下降させる大きなファンを持っています。 –

+0

これは申し訳ありませんが、私は当時調理していましたが、私はコメントを忘れてしまったのでしょうか?x最初に、これはenum <->文字列マッピングの1つのイオタには該当しません。 2番目の*リテラル/定数にはマクロを使用しないでください。より良い選択肢(extern constant、static constantなど)があります。 –

関連する問題