Skip to content

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

Description

@Daveyjonez

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);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions