Field
単独では型ではなく、やなどの型のファミリーを生成できるテンプレートField<int>
ですField<double>
。これらのフィールドはすべて、一方が他方から派生しているなどの関係はありません。したがって、これらすべての生成されたタイプの間に何らかの関係を確立する必要があります。1つの方法は、一般的な非テンプレート基本クラスを使用することです。
class FieldBase { };
template <typename T>
class Field : public FieldBase {
private:
T value;
DataType<T> type;
};
class Row {
private:
std::map<unsigned long,FieldBase*> column;
};
そして、コードでその生のポインターの代わりにスマートポインターを使用することを検討してください。とにかく、今問題はタイプ情報が失われることです-あなたがaを指すかaを指すかはField<double>
もうField<int>
わからず、テンプレート化された派生クラスによって設定されたベースにある種のタイプフラグを保持することによってのみ検出できます-またはを使用してRTTIに質問する
dynamic_cast<Field<int>*>(field) != 0
しかし、それは醜いです。特にあなたが望むものには価値セマンティックがあるからです。つまり、行をコピーできるようにすると、その中のすべてのフィールドがコピーされます。また、doubleが格納されている場合は、最初にRTTIを使用して派生型にハックすることなく、doubleを取得する必要があります。
これを行う1つの方法は、識別された共用体を使用することです。これは基本的に、いくつかの任意の型の和集合であり、さらに、そのフィールドに現在格納されている値(たとえば、double、int、...)を格納するtype-flagです。例えば:
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;
};
boost::variantがすべての作業を行います。訪問を使用して、適切なオーバーロードを使用してファンクターを呼び出すことができます。そのマニュアルを見てください