json icon indicating copy to clipboard operation
json copied to clipboard

Issue when dumping a vector of derived classes

Open myermo opened this issue 5 months ago • 3 comments

Description

I need to serialize a vector composed by derived classes. I have a Container class which holds two variables, one of them being a std::vector<Base>. When dumping the contents of the vector, only the members of the Base class are detected, and the members of the Derived classes are omitted.

Reproduction steps

Just execute the example provided.

https://godbolt.org/z/KbxKs688Y

Expected vs. actual results

Actual Result { "Container": { "a": 2, "data": [ { "b": 3 }, { "b": 5 } ] } }

Expected Result { "Container": { "a": 2, "data": [ { "b": 3, "d": 4 }, { "b": 5, "d": 6 } ] } }

Minimal code example

#include <iostream>
#include "nlohmann/json.hpp"

using json = nlohmann::ordered_json;

// Minimum example of the bug
struct Base
{
  int b{};

  Base(int b) : b(b) {};
};

struct Derived : public Base
{
  int d{};

  Derived(int b, int d) : Base(b), d(d) {};
};

struct Container
{
  int a{};
  std::vector<std::shared_ptr<Base>> v{};

  Container(int a, std::vector<std::shared_ptr<Base>> v) : a(a), v(v) {};
};

void to_json(json& j, const std::shared_ptr<Base>& b)
{
  j = json{{"b", b->b}};
}

void to_json(json& j, const std::shared_ptr<Derived>& d)
{
  j = json{{"b", d->b}};
  j.update("d", d->d);
}

void to_json(json& j, const std::shared_ptr<Container>& c)
{
  j = json{ { "a", c->a } , { "data", c->v } };
}

void createOutputJson()
{
  json j;

  auto d1 = std::make_shared<Derived>(3, 4);
  auto d2 = std::make_shared<Derived>(5, 6);

  std::vector<std::shared_ptr<Base>> v2 = {d1, d2};

  auto C = std::make_shared<Container>(2, v2);

  j["Container"] = C;

  std::cout << j.dump(4) << std::endl;
}

int main() {
    createOutputJson();
}


### Error messages

```Shell
N/A

Compiler and operating system

Arch Linux, GCC 14.2.1 and CLANG 19.1.0

Library version

b36f4c47

Validation

myermo avatar Sep 18 '24 08:09 myermo