Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How can I get this simple example working? #1926

Closed
markeastwood82 opened this issue Feb 4, 2020 · 2 comments
Closed

How can I get this simple example working? #1926

markeastwood82 opened this issue Feb 4, 2020 · 2 comments

Comments

@markeastwood82
Copy link

markeastwood82 commented Feb 4, 2020

  • Describe what you want to achieve.
    I want to see a simple example working before integrating into my library. The following code (single file) compiles ok but the json dump is an empty array. It doesn't seem like the to_json and from_json functions are ever being called but I get no warnings or exceptions thrown. How do I modify this code to get something working?
#include <nlohmann/json.hpp>
using nlohmann::json;

#include <string>
#include <iostream>

namespace orchard {

class Apple {
public:
    Apple() {}
    std::string colour;
    int tastiness;
    bool ripe;
};

class AppleTree {
public:
    AppleTree() {}
    double height;
    std::vector<Apple> apples;
};

void to_json(json& j, const Apple& a)
{
    std::cout << "serializing Apple" << std::endl;
    j = json{{"colour", a.colour}, {"tastiness", a.tastiness}, {"ripe", a.ripe}};
}

void from_json(const json& j, Apple& a)
{
    std::cout << "deserializing Apple" << std::endl;
    j.at("colour").get_to(a.colour);
    j.at("tastiness").get_to(a.tastiness);
    j.at("ripe").get_to(a.ripe);
}

void to_json(json& j, const AppleTree& t)
{
    std::cout << "serializing Apple Tree" << std::endl;
    j = json{{"height", t.height}, {"apples", t.apples}};
}

void from_json(const json& j, AppleTree& t)
{
    std::cout << "deserializing Apple Tree" << std::endl;
    j.at("height").get_to(t.height);
    j.at("apples").get_to(t.apples);
}

} // orchard

int main() {

    // Get some data
    std::vector<orchard::AppleTree> trees;
    trees.reserve(2);
    for (uint i=0; i<2; i++) {
        trees[i].height = i+2;
        trees[i].apples.reserve(3);
        for (uint j=0; j<3; j++) {
            trees[i].apples[j].tastiness = static_cast<int>(3*j - j*j);
            trees[i].apples[j].ripe = j > 1;
            trees[i].apples[j].colour = "red";
        }
    }

    // Serialize
    json _json(trees);
    std::string dump = _json.dump();
    std::cout << dump << std::endl;

    // Deserialize
    json _json2 = json::parse(dump);
    auto trees2 = _json2.get<std::vector<orchard::AppleTree>>();

    // Show that it worked
    try {
        std::cout << trees2.at(0).apples.at(0).colour << std::endl;
    } catch (std::out_of_range) {
        std::cout << "didn't work" << std::endl;
    }

    return 0;
}

I am using conan to provide nlohmann_json using this conanfile.txt

[requires]
nlohmann_json/3.7.0

[generators]
cmake_find_package

and my CMakeLists.txt file is simply

cmake_minimum_required(VERSION 3.1)
project(json-muck)

list(APPEND CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR})
find_package(nlohmann_json REQUIRED)

add_executable(muck src/main.cpp)
target_link_libraries(muck nlohmann_json::nlohmann_json)
set_property(TARGET muck PROPERTY CXX_STANDARD 11)

  • Describe what you tried.
    Have tried breaking into separate header file to contain the class and conversion functions and a main file. Have tried using structs instead of classes and providing more constructors as per the instructions.

  • Describe which system (OS, compiler) you are using.
    Ubuntu 18.04, gcc version 9.2.1 20191008

  • Describe which version of the library you are using (release version, develop branch).
    nlohmann_json/3.7.0

Thanks in advance

@nickaein
Copy link
Contributor

nickaein commented Feb 4, 2020

Instead of reserve(), you must do resize() (or reserve() + push_back()). A reserve() on vector only changes the underlying buffer size and doesn't logically increases the size of the vector. Therefore, your vectors are considered empty. More info on difference between resize() vs. reserve().

@markeastwood82
Copy link
Author

Thankyou!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants