Зерновые - невозможно десериализовать строку json - необработанное исключение

Это моя строка json

{
    "connectionString" : "MyConnectionString",
    "value" :"MyVal"
}

это мой класс

        struct Settings
        {
            std::string connectionString;
            std::string value;

            template<class Archive>
            void serialize(Archive& ar)
            {
                    ar(CEREAL_NVP(connectionString),
                    CEREAL_NVP(value)
                );
            }
        };

И вот что я делаю:

            std::ifstream ifs("Settings.json");
            std::string content((std::istreambuf_iterator<char>(ifs)),(std::istreambuf_iterator<char>())); // Yes this is valid - The content gets populated
            
            Settings settings;
            {
                cereal::JSONInputArchive archive_in(ifs);
                archive_in(settings); //<<-----Exception here - Unhandled exception
            }

Приведенное выше решение будет работать, только если моя строка json будет такой (т.е.), если вся строка json будет объектом другого ключа.

{
    "SomeThing" :{
                "connectionString" : "MyConnectionString",
                "value" :"MyVal"
       }
}

Мой вопрос в том, как я могу заставить свою настоящую строку json работать (без переноса ее в объект)? В настоящее время у меня есть это в файле json

{
    "connectionString" : "MyConnectionString",
    "value" :"MyVal"
}

и я хотел узнать, как лучше всего десериализовать это в объект?


person Rajeshwar    schedule 16.11.2020    source источник
comment
Что это за исключение? Вы искали документацию для оператора вызова archive_in, чтобы узнать, что это означает в этом контексте? Вы убедились, что поток ifs действителен? Вы убедились, что строка content содержит то, что, по вашему мнению, должно быть? Зачем вы создаете поток, извлекаете его содержимое, а потом из них сразу создаете другой поток? Почему бы просто не передать ifs конструктору archive_in? Так много вопросов...   -  person Asteroids With Wings    schedule 16.11.2020
comment
@AsteroidsWithWings Я использовал ifs вместо создания потока. Также да, содержание действительно. Я также добавил тип исключения, которое я получаю   -  person Rajeshwar    schedule 17.11.2020
comment
Хорошо, а что насчет остального   -  person Asteroids With Wings    schedule 17.11.2020
comment
@AsteroidsWithWings, можете ли вы сказать мне, что мне не хватает? Кажется, я ответил на все ваши вопросы? Пожалуйста, поправьте меня, если я ошибаюсь   -  person Rajeshwar    schedule 17.11.2020
comment
Вы ответили на три из них. Я спросил больше, чем три.   -  person Asteroids With Wings    schedule 17.11.2020


Ответы (1)


Код, ожидающий, что внешний объект будет помещен туда по умолчанию в прологе и эпилоге JSON:

https://github.com/USCiLab/cereal/blob/10d9a29c225fe9a843d043bfe9f13c5f958844dc/include/cereal/archives/json.hpp#L837

Из документации:

Эти функции получают ссылку на активный архив и постоянную ссылку на сериализуемый тип. Тщательная специализация пролога и эпилога позволяет архивам проявлять особое поведение без необходимости повторной реализации функций сериализации для типов. Это позволяет нам сделать поддержку типов довольно универсальной. Например, хлопья::XMLOutputArchive (‹cereal/archives/xml.hpp›) использует эти функции для запуска и завершения узлов в своем дереве в памяти.

Если вы добавите в свой код перегрузку для вашего типа, которая ничего не делает:

void epilogue(cereal::JSONInputArchive&, const Settings&) { }
void prologue(cereal::JSONInputArchive&, const Settings&) { }

Он не будет пытаться анализировать внешний объект

person parktomatomi    schedule 19.11.2020
comment
Круто, что получилось!! Также есть вероятность, что вы знаете, почему это не работает, если переменные в классе настроек сделаны статическими? - person Rajeshwar; 19.11.2020
comment
Не сразу приходит мне в голову, но мне кажется, что это связано с поиском, зависящим от аргумента. - person parktomatomi; 19.11.2020
comment
статические данные работали нормально для меня. Но макрос CEREAL_NVP не удался из-за того, что область видимости (::) перепутала имя свойства. Пришлось использовать ::cereal::make_nvp("name", Settings::value) - person parktomatomi; 19.11.2020