为什么您希望容器具有不同的对象可能是一个设计缺陷。然而,一些语言支持这一点,例如 Smalltalk,它具有可以包含不同对象类型混合的 Bag Collection 的概念。Qt 可能已经有某种袋子容器类,但我不知道它的存在。
这种在单个容器中混合类型的概念在 C++ 的强类型世界中并不适用。变体对象是最接近的东西,即便如此,如果没有创建自己的“超级变体”类,您可以通过子类化QVariant
然后添加一些位来处理您的结构来实现非整数类型。
再次问自己为什么需要这个功能?在其他地方实施的更简单的解决方案可能会减轻对这种容器的需求。
编辑:QMap<QString, QVariant>
帮助确定这是否可行的快速示例。
class SomeObject
{
public:
SomeObject() // default
: someInt(0), someDouble(0) {}
SomeObject(int i, double d) // explicit
: someInt(i), someDouble(d) {}
int GetSomeInt() const { return someInt; }
double GetSomeDouble() const { return someDouble; }
private:
int someInt;
double someDouble;
};
// must be outside of namespace
Q_DECLARE_METATYPE(SomeObject)
// then you can do stuff like this:
QMap<QString, QVariant> mapNameToValue;
// populate map
mapNameToValue["UserName"] = "User";
mapNameToValue["Port"] = 10101;
mapNameToValue["PI"] = 3.14159265;
mapNameToValue["DateTime"] = QDateTime::currentDateTime();
QVariant userValue;
userValue.setValue(SomeObject(5, 34.7));
mapNameToValue["SomeObject"] = userValue;
// read from map
QString userName = mapNameToValue["UserName"].toString();
unsigned int port = mapNameToValue["Port"].toUInt();
double PI = mapNameToValue["PI"].toDouble();
QDateTime date = mapNameToValue["DateTime"].toDateTime();
SomeObject myObj = mapNameToValue["SomeObject"].value<SomeObject>();
int someInt = myObj.GetSomeInt();
double someDouble = myObj.GetSomeDouble();
QVariant
处理很多类型,它也有模板方法setValue
和value<>
用户定义的类型。如上所示,您必须使用Q_DECLARE_METATYPE
宏来注册它QMetaType
并提供默认构造函数以防value<>
转换失败。它不支持某些比较运算符,所以我会制作我自己的版本,QVariant
并且QMetaType
可以很好地处理所需的任何额外类型,因此感觉更加一致。