QJsonArrays неправильно извлекаются из QJsonObject - PullRequest
0 голосов
/ 09 мая 2020

В проекте, над которым я сейчас работаю, я использую функциональность Qt JSON для хранения состояния графа, где каждый компонент системы рекурсивно вызывает toJson -функции своих членов для сериализации. Это работает нормально, но я столкнулся со странной проблемой при десериализации файла JSON.

В качестве теста, иллюстрирующего проблему, я создал следующий пример кода:

#include <QtCore/QJsonArray>
#include <QtCore/QJsonDocument>
#include <QtCore/QJsonObject>
#include <QtDebug>

int main() {
  auto document{QJsonDocument::fromJson("{\n"
                                        "  \"o1\" : {\n"
                                        "    \"i1\" : [\"l1\", \"l2\", \"l3\"],\n"
                                        "    \"i2\": 3.14\n"
                                        "  },\n"
                                        "  \"o2\" : {\n"
                                        "    \"i2\": 2.718,\n"
                                        "    \"i1\" : [\"l1\", \"l2\", \"l3\"]\n"
                                        "  }\n"
                                        "}")};
  qDebug() << "is the document an object:" << document.isObject();
  auto document_object{document.object()};

  auto object_1_value{document_object.value("o1")};
  qDebug() << "is o1 an object:" << object_1_value.isObject();
  auto object_1{object_1_value.toObject()};

  auto inner_1_value{object_1.value("i1")};
  qDebug() << "is i1 an array:" << inner_1_value.isArray();
  auto inner_1{inner_1_value.toArray()};
  qDebug() << "i1:" << inner_1;

  auto inner_1_inner_value{inner_1.at(0)};
  qDebug() << "is i1[0] an array:" << inner_1_inner_value.isArray();
  auto inner_1_inner{inner_1_inner_value.toArray()};
  qDebug() << "i1[0]:" << inner_1_inner;

  return 0;
}

Здесь я сначала запрашиваю o1, а затем пытаюсь получить массив, хранящийся в i1. Однако я получаю следующий результат:

is the document an object: true
is o1 an object: true
is i1 an array: true
i1: QJsonArray([["l1","l2","l3"]])
is i1[0] an array: true
i1[0]: QJsonArray([["l1","l2","l3"]])

Похоже, что Qt сохраняет возвращенный массив в бесполезный одноэлементный массив; в моем другом коде at(0) решил проблему, но здесь даже это не работает.

Я был бы очень рад, если бы кто-нибудь мог помочь мне найти решение для надежного (и желательно без взлома) чтения вложенных JSON массивы с Qt, так как я действительно не понимаю проблемы. Я использую Linux 5.6.11 с g cc 9.3.0 и Qt 5.14.2.

1 Ответ

0 голосов
/ 09 мая 2020

Ваша проблема - инициализация скобок. Когда вы вместо этого выполняете инициализацию в стиле присваивания, это работает.

// instead of
auto inner_1{inner_1_value.toArray()};
// use
auto inner_1 = inner_1_value.toArray();
// same for all other brace inits

Я думаю, что происходит класс случай этот:

QJsonArray::QJsonArray(std::initializer_list<QJsonValue> args);

Вы хотите использовать brace-init a QJsonArray, но std::initializer_list имеет приоритет, и вы фактически создаете экземпляр QJsonArray с одним элементом, который снова является QJsonArray .

Часто вы видите, что эта проблема объясняется с помощью std::vector<int> и двух конфликтующих ctors:

vector(size_type count);
vector(std::initializer_list<int> init);
...