Почему вы хотите, чтобы в контейнере были разнородные объекты, это, вероятно, недостаток дизайна.Однако некоторые языки поддерживают это, например Smalltalk, который имеет концепцию Bag Collection, которая может содержать смесь различных типов объектов.У Qt уже может быть какой-то класс контейнера-мешка, но я не знаю о его существовании.
Эта концепция смешанных типов в одном контейнере не очень хорошо работает в строго типизированном мире C ++.Вариантные объекты - это самая близкая вещь, и даже не для нецелых типов без создания собственного «супервариантного» класса, который вы можете сделать, создав подкласс QVariant
, а затем добавив несколько битов для обработки своих структур.вопрос зачем вам этот функционал?Более простое решение, реализованное в другом месте, вероятно, уменьшит потребность в таком контейнере.
Редактировать: пример Quickie из 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
, чтобы она хорошо играла с любыми необходимыми дополнительными типами, чтобы она выглядела более согласованной.