C++std::地図のテンプレートクラスの価値
質問
いることを宣言す Row
や Column
クラスは、 Row
有する個人 std::map
との値差は、分子を鋳型とし Column
.のようなこと:
template <typename T> class DataType {
private:
T type;
};
template <typename T> class Field {
private:
T value;
DataType<T> type;
};
class Row {
private:
std::map<unsigned long,Field*> column;
};
かも原則として、 Row
クラスのないような Field
( Column
)あるいを使用するか Field<int>
列1 Field<double>
列2.でもお使いいただくことによっては正しい構文の Row::column
宣言である場合、又は std::map
はこの意味で、私は利用もかかりました。
I appretiateご提案をありがとうございましたっています。
解決
のみField
はタイプではありませんが、そのようなField<int>
やField<double>
ようなタイプの家族を生成することができますテンプレート。すべてのこれらのフィールドは、一つは何とか他のかなどに由来するものであっても関係ありません。だから、あなたは、これらすべての生成された型の間に何らかの関係を確立する必要があります。一つの方法は、一般的な非テンプレートベースクラスを使用することです。
class FieldBase { };
template <typename T>
class Field : public FieldBase {
private:
T value;
DataType<T> type;
};
class Row {
private:
std::map<unsigned long,FieldBase*> column;
};
そしてスマートポインタの代わりに、コードでその生のポインタを使用することを検討してください。とにかく、今の問題は、型情報が失われることである - あなたはもう知られていないField<double>
やField<int>
を指すだけテンプレートで設定されているベースタイプフラグのいくつかの並べ替えを維持することによって検出することができるかどうか派生クラス - または
dynamic_cast<Field<int>*>(field) != 0
しかし、それは醜いです。特に、あなたは意味値がある何をしたいので。すなわち、あなたの行をコピーできるようにしたいでしょう、そして、それはそれですべてのフィールドをコピーします。最初の派生型にあなたの方法をハックするRTTIを使用せずに - そして、あなたは、二重に格納されている場合、ダブルを取得したいと思います。
これを行う1つの方法は、差別組合を使用することです。すなわち、(例えば二重、INT、...かどうか)は、基本的に現在そのフィールドに格納されているものの値を記憶いくつかの任意のタイプの組合と加えタイプフラグ、です。たとえばます:
template <typename T>
class Field {
private:
T value;
DataType<T> type;
};
class Row {
private:
std::map<unsigned long,
boost::variant< Field<int>, Field<double> > >
column;
};
ブースト::バリアントがあなたのためにすべての作業を行います。あなたはそれが右のオーバーロードを使用してファンクタを呼び出す作るために訪問を使用することができます。マニュアルのrel="noreferrer">その
他のヒント
- またエラーもコメントありがとうございますい"価値"会場(ばしょうが"型").
- 再発防止の効果が得られます。原のポインタのマップの値です。使用 ブ::shared_ptr.
- また、すべての理由を書き込みなど授業がたくさんありDB/テーブルに取り扱いコードになっているできるのではないでしょうか。そのため、などに使用できます。使用を考慮するか、既存の、書かない自分のテーブル取り扱います。
現在、回答のご質問、分野<>授業に引き継ぐから共通の基底クラス共有される全てのデータです。このようにコンテナなどのカラムを地図でポイント(それ 共有 ポインタ)に由来しているオブジェクトがinstancedテンプレートのクラスです。
Row< int, float, int>
はRow<int, std::string>
から本当に異なっています。
Row<int,float,int>.field<0>
はField<int>
する必要がありながら、明らかに、Row<int,float,int>.field<1>
はField<float>
でなければなりません。そしてRow<int,float,int>.field<3>
は、コンパイラエラーです。
そうするための最も簡単な方法は、ブーストを使用しています。知性の全体の多くは、ロキ(参照 の現代C ++の設計によって開拓されましたの、アンドレイアレキによる)が、サポート、より近代的で優れているのブースト。
通常は、フィールドを反復しません - それぞれのフィールドには、独自の型を持ちます。しかし、あなたの、あなたは確かにFieldBase
が必要になります。あなたは、このようなインターフェイスが必要な場合、それはまた、boost::array<FieldBase, N>
(すなわちRow<int,float,int>
がboost::array<FieldBase, 3>
を持っている)として内部フィールドを保存するために、おそらく価値があります。あなたはしかし、そのdynamic_cast
をFieldBase*
する必要はありません。これは、実行時のテストで、あなたは常にコンパイル時に各T
の正確なField<T>
を知っています。