-1

Using https://github.com/nlohmann/json, I am trying to assign values to a recursive data structure (json_node_t):

#include <iostream>
#include <string>
#include <vector>
#include "json.hpp"

using namespace std;
using json = nlohmann::json;

struct json_node_t {
    int id;
    std::vector<json_node_t> children;
};

void to_json(json& j, const json_node_t& node) {
    j = {{"ID", node.id}};
    if (!node.children.empty())
        j.push_back({"children", node.children});
}

int main() {
    json_node_t node_0;
    std::vector<int> values = {1,2,3};

    std::vector<json_node_t> parents;
    parents.resize(20);

    for(int i = 0; i < values.size(); i++) {

        if ( i == 0 )
        {
            node_0.id = values[0];
            std::vector<json_node_t> node_children_;
            node_0.children = node_children_;
            parents[0] = node_0;

        } else {

            json_node_t node_i;
            node_i.id = values[i];

            std::vector<json_node_t> node_i_children_;
            parents[i] = node_i;

            parents[i-1].children.push_back(node_i);
        }
    }

    json j = node_0;

    cout << j.dump(2) << endl;
    return 0;
}

My purpose is to create a JSON representation like the following:

{
  "ID": 1,
  "children": [
    {
      "ID": 2
    },
    {
      "ID": 3,
      "children": []

    }
  ]
}

However, the nested children are not getting printed. I only get this output:

{
  "ID": 1
}

What is wrong? I cannot connect the child to his parent correct. How can I fix the problem?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
cateof
  • 6,608
  • 25
  • 79
  • 153
  • 1
    Note that [you can't actually do that](https://stackoverflow.com/questions/18672135/why-c-containers-dont-allow-incomplete-types) in current C++. – juanchopanza Aug 31 '17 at 19:24
  • Would you mind to change your question title to something meaningful and helpful for future research about that particular problem please? – user0042 Aug 31 '17 at 20:09

1 Answers1

0

You output node_0;, but you never append any children to it. The reason for that, is parents[0] = node_0; copies node_0. So when you parents[0].children.push_back(node_i); you append node_i as a child to the copy of node_0 - the original one remains unchanged. That is why it contains no children in the end.

EDIT: My code.

#include "json.hpp"

#include <memory>
#include <vector>
#include <iostream>

struct json_node;
using json_node_ptr = std::shared_ptr<json_node>;

struct json_node
{
    int id;
    std::vector<json_node_ptr> children;

    json_node(int _id)
        : id{ _id }
    {
    }
};

void to_json(nlohmann::json& j, const json_node_ptr& node)
{
    j = {{"ID", node->id}};
    if (!node->children.empty()) {
        j.push_back({"children", node->children});
    }
}

int main()
{
    std::vector<int> values = {1,2,3};
    std::vector<json_node_ptr> parents;

    for(int i = 0; i < values.size(); i++)
    {
        if ( i == 0 ) {
            auto root = std::make_shared<json_node>(values[0]);
            parents.push_back(root);
        } else {
            parents.push_back(std::make_shared<json_node>(values[i]));
            parents[i-1]->children.push_back(parents[i]);
        }
    }

    nlohmann::json j = parents[0];
    std::cout << j.dump(2) << std::endl;

    return 0;
}

Output:

{
  "ID": 1,
  "children": [
    {
      "ID": 2,
      "children": [
        {
          "ID": 3
        }
      ]
    }
  ]
}
WindyFields
  • 2,697
  • 1
  • 18
  • 21
  • @cateof, The question was "What is wrong?" :) The obvious fix would be to store the pointers to nodes and allocate your nodes dynamically. This way if `std::vector parents;` then `parents[i - 1]-> children.push_back(node_i);` would refer to the original node. – WindyFields Aug 31 '17 at 19:45
  • Of course, `node_0` and `node_i` have to be pointers too... I hope you got the idea – WindyFields Aug 31 '17 at 19:47
  • Thanks @WindyFields, your approach helped me resolved the problem – cateof Sep 01 '17 at 12:45