2011-12-21 11 views
3

実行時に変数で使用できるデータ型を持つテンプレートクラスをインスタンス化する必要があります。たとえば、このクラスを考えてみましょう。C++で変数からテンプレート引数を指定する

template <typename T, unsigned int U> 
class Allocator 
{ 
public: 
    T * pointer; 
    Allocator() { pointer = new T[U]; } 
    ~Allocator() { delete [] pointer; } 
}; 

は今、私はこのようにそれを使用したい:

int main() 
{ 
    string temp = "int"; 
    unsigned int count = 64; 
    Allocator<temp, count> a; 
    return 0; 
} 

これを行う方法はありますか?

私は、派生クラスをベースポインタでシリアル化するコンテキストでこの問題に直面しています。 RTTIを使って派生クラスの実際の型を識別しますが、実際の型の情報は文字列に格納されます。私の問題は、基本ポインタから型(実行時に文字列として利用可能)にdynamic_castできるようにすることです。助けてください。

+0

Uがコンストラクタのパラメータの代わりにテンプレートパラメータでなければならない理由はありますか? –

+0

上記は実際の問題の例です。これは、この特定のケースでUをコンストラクタ引数にすることによって簡単に解決できますが、私はこれを実際の問題に到達するための例として取っています... – Somesh

答えて

1

できません。コンパイル時にデータ型を知っている必要があります。 Boostやunionを使用していると、問題が解決しないかもしれません。

幸運を祈る!

+0

私が考えることができた方法の1つは、プロトタイプパターン。ルックアップテーブルがすべての可能なタイプのアロケータ(実際にアプリケーションで使用されている)のために存在する場合、ストリング(テーブルの「キー」)として利用可能なデータ型を使用し、適切なアロケータポインタは、テーブルのキーの「値」です)。しかし、このアプローチでは、私は依然として 'Allocator 'というポインタを登録する必要があります。ここでは、XXXはすべての可能なサイズを一度に1つずつスイープします。これを避けるための回避策はありますか? – Somesh

+0

これについてもう少し考えてみたら、なぜこれができないのか理解できるようになりました。テンプレートに基づくコード生成が*コンパイル時アクティビティ*であるという事実が理由です。コンパイラはコンパイル時に変数の内容を知らないため、テンプレートのインスタンス化時に生成するコードを特定できません。提案に感謝します。 – Somesh

+0

ようこそ。幸運;) – Drewen

1

C++での反射メカニズムがないため、直接言語サポートのあるデータに基づく「動的作成」が不可能になります。

唯一の方法は、タイプを宣言する文字列を作成関数呼び出しに関連付けるディスパッチマップを所有するファクトリクラスのような、「スイッチ」または同等の宣言メカニズムを使用することです。

+0

これも私が考えていることです(Drewenの答えに対する私のコメントを参照)。しかし、問題は、与えられたデータ型のために、 'int'と言うと、すべての可能なサイズのAllocatorsのポインタをマップに格納しなければならないということです。これを自動化する方法があることを願っています。 – Somesh

+0

意味は、キーとして 'int'を、値として別のマップを格納するマップを持ちます。第2の(値)マップでは、キーはサイズ(例えば64)であり、値は実際のアロケータ( 'Allocator *')へのポインタです。今度はクローンを作成するのは簡単です...逆に、2番目の(値)マップには、すべての可能なサイズ(または少なくともプログラムで使用可能なサイズ)のAllocatorポインタが必要です。 – Somesh

+0

@Somesh:それはちょっと複雑すぎるが、意味的には同等だと思う。それは何よりも(宣言された)宣言的な構造に過ぎません。それはあなたがより快適に感じるようにする場合...なぜではない! –

関連する問題