如何在C++中使用std::optional< std::variant >类型解析JSON文件?

3

我该如何在C++中解析嵌套的 JSON?我正在寻找一个能够解析嵌套 JSON 的 JSON 解析器,特别是下面示例 JSON 中的字段:

optional<variant<bool, Secondary>> secondary;

它是optionalvariant的类型组合。

虽然只有完整的示例才能更清楚地展现问题,但以下是最小起始点示例:

    [
      {},
      {
        "secondary": false
      },
      {
    
        "secondary": {
          "chance": 10,
          "boosts": {
            "spd": -1
          }
        }
      },
      {
        "secondary": {
          "chance": 30,
          "volatileStatus": "flinch"
        }
      },
      {
        "secondary": {
          "chance": 30
        }
      },
      {
        "secondary": {
          "chance": 10,
          "self": {
            "boosts": {
              "atk": 1,
              "def": 1,
              "spa": 1,
              "spd": 1,
              "spe": 1
            }
          }
        }
      },
      {
        "secondary": {
          "chance": 10,
          "status": "brn"
        }
      },
      {
        "secondary": {
          "chance": 50,
          "self": {
            "boosts": {
              "def": 2
            }
          }
        }
      },
      {
        "secondary": {
          "chance": 100,
          "self": {}
        }
      },
      {
        "secondary": {
          "chance": 50,
          "boosts": {
            "accuracy": -1
          }
        }
      }
    ]

以下是我已经有的内容:

struct Boosts {
    optional<int> atk;
    optional<int> def;
};

struct Self {
    optional<Boosts> boosts;
};
struct Secondary {
    optional<int> chance;
    optional<string> volatileStatus;
    optional<Boosts> boosts;
    optional<Self> self;
    optional<string> status;
};

struct move_t {
    int num;
    variant<bool, int> accuracy;
    int basePower;
    string category;
    optional<string> desc = std::nullopt;
    string shortDesc;
    string id;
    string name;
    optional<variant<bool, Secondary>> secondary;

};
1个回答

2
我宁愿在“std::variant”的第一个类型参数中滥用“std::monostate”,也不愿在“std::variant”上使用“std::optional”。如果变量包含monostate,则表示为空的变量。 顺便问一下,既然有“boost::property_tree”可用,为什么要重新发明轮子?

https://www.boost.org/doc/libs/1_72_0/doc/html/property_tree.html


看到需要解析的完整JSON,我没有看到其他的方法。这种类型使用Scala和Haskell可以工作,不确定在C++中是否可以以某种方式实现。 - cpchung
我觉得我对你的意图有些误解。但是提供的boost库链接应该没问题。看一下吧。你可以使用同样的库和类来解析XML、INI和一个不太常见的INFO格式。 - Red.Wave
这里有一个正在进行的尝试,使用nlohmann json库: https://github.com/nlohmann/json/issues/1910 - cpchung
我检查了property_tree,它提供了toString()方法,但我认为它不适合解析json并在编译时提供静态类型支持,例如能够通过类定义中的字段访问元素而不是动态访问字段,这可能会导致错误。 - cpchung
@Red.Wave 我同意cpchung的观点,即property_tree不会检查所引用的键是否实际上在json中。如果属性(例如battle)在json对象j中,则我希望使用j.battle而不是j["battle"]来引用它。 - lmln
@lmln 你有麻烦了:C++没有内置的反射支持。但是有一些库和非标准扩展可以解决这个问题。 - Red.Wave

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接