cerealのJSONフォーマットで最後の波括弧が抜ける問題

Unityのゲームデータ保存で紹介されたシリアライズの方法がなかなかいい感じがしたので、C++の場合でも同じ方法を採用してみたいと思い、C++のシリアライズライブラリcerealを使ってみました。

デモプログラムは無事動作したことを確認し、いざ本番実装となると、構造体をJSONフォーマット(OUT)に変えられましたが、その逆(IN)ができませんでした。
調べたところ、出力(OUT)した結果の一番最後の括弧が抜けることが分かりました。
こんな感じです:

{
    "value0": {
        "value0": 1,
        "value1": 2,
        "value2": 1.5
    }
// 本来ならここにもう一つの波括弧がなくてはいけません

これなら当然JSONとして読み込まず、下記のようなエラーが出ます。

Error: rapidjson internal assertion failure: IsObject()

参考2は同じ問題で、なんと解決策は括弧ブロックにありました。
エラーの例:

int main()
{
  std::stringstream ss;

  cereal::JSONOutputArchive archive( ss );
  SomeData myData;
  archive( myData );

  std::cout << ss.str() << std::endl;

  return 0;
}

正しい例:

int main()
{
  std::stringstream ss;
  { // このブロックがないとダメです。
    cereal::JSONOutputArchive archive( ss );
    SomeData myData;
    archive( myData );
  }
  std::cout << ss.str() << std::endl;

  return 0;
}

デモプログラムのstringstream直後の波括弧ブロックはただソースの見た目をよくするためだと思いましたが、動きまで異なるとは勉強になりました。

参考
  1. cereal – A C++11 library for serialization
  2. The output of json archive using std::stringstream as Output will miss the last “}”
コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です