Почему вы хотите, чтобы контейнер имел разнородные объекты, вероятно, является дефектом дизайна. Однако некоторые языки поддерживают это, например Smalltalk, который имеет концепцию коллекции пакетов, которая может содержать сочетание разных типов объектов. У Qt может быть какой-то класс контейнера для пакетов уже, но я не знаю о его существовании.
Эта концепция смешанных типов в одном контейнере не работает так хорошо в строго типизированном мире C++. Объекты Variant являются ближайшими, и даже тогда не для нецелевых типов, не создавая свой собственный класс супервыражений, который вы могли бы сделать путем подкласса 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
, чтобы играть хорошо с любыми дополнительными типами, поэтому он чувствует себя более последовательным.
Какую проблему вы действительно пытаетесь решить здесь? –
Сериализация JSON в простые в использовании конструкции C++ .. –