我试图声明一个Row
和一个Column
类,Row
有一个私有std::map
值指向模板Column
.像这样的东西:
templateclass DataType { private: T type; }; template class Field { private: T value; DataType type; }; class Row { private: std::map column; };
好吧,我原则上认为Row
类不应该知道我们想要使用哪种Field
(或Column
),即它是第1 Field
列还是第Field
2列.但是我不确定什么是正确的语法对于Row::column
声明,或者如果std::map
它在这个意义上是有限的,我应该使用其他东西.
我建议你提出建议,并提前感谢你们.
Field
单独不是一种类型,而是一种可以生成一系列类型的模板,例如Field
和Field
.所有这些字段都不相关,使得一个字段以某种方式从另一个或那样派生.所以你必须在所有这些生成的类型之间建立一些关系.一种方法是使用通用的非模板基类:
class FieldBase { }; templateclass Field : public FieldBase { private: T value; DataType type; }; class Row { private: std::map column; };
并考虑在代码中使用智能指针而不是原始指针.无论如何,现在问题是类型信息丢失了 - 无论你指向a Field
还是a Field
都不知道,只能通过在模板派生类设置的基数中保留某种type-flag来检测它. - 或者通过询问RTTI
dynamic_cast*>(field) != 0
但那很难看.特别是因为你想要的是一个价值语义.也就是说,你希望能够复制你的行,它会复制其中的所有字段.并且你想要在存储双精度时得到一个双精度 - 而不是先使用RTTI来破解你的派生类型.
一种方法是使用有区别的联合.这基本上是一些任意类型的并集,另外还有一个type-flag,它存储当前存储在该字段中的值(例如,是否为double,int,...).例如:
templateclass Field { private: T value; DataType type; }; class Row { private: std::map , Field > > column; };
boost :: variant为您完成所有工作.您可以使用访问来使用正确的重载来调用仿函数.看看它的手册