cereal icon indicating copy to clipboard operation
cereal copied to clipboard

C++ 11: Unable to use try / catch optional field with in JSON arrays

Open Daveyjonez opened this issue 9 months ago • 1 comments

In C++ 11, it seems that a try / catch is the only way of achieving optional values. This works with singular JSON objects, but as soon as they are included in a JSON array, the optional-ness fails and is the NVP becomes required for all objects in the array. Is there any workaround for this use case?

Code to reproduce:

#include "cereal/archives/json.hpp"
#include "cereal/cereal.hpp"
#include "cereal/types/vector.hpp"
#include "gtest/gtest.h"

class foo
{
public:
    size_t number {0};
    bool optional {true};

    template<class Archive>
    void serialize(Archive &ar)
    {
        ar(CEREAL_NVP(number));

        // Optional Overrides
        try {
            ar(CEREAL_NVP(optional));
        }
        catch (...){
            std::cout << "Skipping optional" << std::endl;
        }
    }
};


class bar{

public:
    std::vector<foo> foos;

    template<class Archive>
    void serialize(Archive &ar)
    {
        ar(CEREAL_NVP(foos));
    }
};

TEST(ARR_TEST, test) {
    // passes
    const std::string foo_str = R"({
        "test": {"number":1}
    })";
    foo f;
    {
        std::istringstream is(foo_str);
        cereal::JSONInputArchive archive(is);
        archive(f);
    }
    EXPECT_EQ(f.number, 1);
    EXPECT_TRUE(f.optional);

    // fails
    const std::string bar_str = R"({
        "test": {
            "foos": [{"number":1}, {"number": 2}]
        }
    })";
    bar b;
    {
        std::istringstream is(bar_str);
        cereal::JSONInputArchive archive(is);
        archive(b);
    }
    EXPECT_EQ(b.foos.size(), 2);
}

Daveyjonez avatar Apr 07 '25 20:04 Daveyjonez

您的邮件我已收到,谢谢合作!

redchairman avatar Apr 07 '25 20:04 redchairman