c++ - 将 JSON 对象作为 Boost 中的键值对插入现有 JSON 对象中

标签 c++ json boost

我有一个如下所示的类层次结构:类 A 由类 B 和 C 组成。 B 和 C 都有一个返回 boost::json::object 的函数,在 B 的情况下看起来像这样: {"B": "someValue"}

A 应该将这些对象中的每一个组合成如下结构:

{
  "A": {
    "B": "someValue",
    "C": "someOtherValue"
  }
}

我面临的问题是,生成的对象总是如下所示:

{
  "A": [
    { "B": "someValue" },
    { "C": "someOtherValue" }
  ]
}

正如您所看到的,子类中的对象不是作为键值对添加的,而是作为对象(每个对象包含单个对)添加到数组中。

这是重现该问题的代码片段:

#include <iostream>
#include <boost/json.hpp>

using namespace boost::json;

object makeObject(std::string key, int value)
{
    object obj;
    obj[key] = value;
    return obj;
}

int main() {
    object obj;
    obj["main"] = {makeObject("test1", 123), makeObject("test2", 456)};

    std::cout << obj << std::endl;
    return 0;
}

根据 boost 的 Quick Look 文档,我预计这不会创建其中包含单值对象的数组。 我在这里做错了什么?

编辑

我根据sehe的回答修改了我的示例:

#include <iostream>
#include <boost/json.hpp>

auto makeProp(string_view name, value v)
{
    return object::value_type(name, std::move(v));
}

int main() {
    object obj;
    obj["main"] = {makeProp("test1", 123), makeProp("test2", 456)};

    std::cout << obj << std::endl;
    return 0;
}

但这仍然会产生不需要的输出,除非我犯了错误:

{"main":[["test1",123],["test2",456]]}

为了进一步详细说明辅助函数的用例,我最初打算快速编写这篇文章,以重现我在上面的类层次结构中描述的问题。

我制作了一个更长的程序,希望以更容易理解的方式显示问题:

#include <boost/json.hpp>
#include <iostream>

using namespace boost::json;

class B
{
public:
    key_value_pair makeProp()
    {
        value v = {"property1", 1};
        return object::value_type("B", std::move(v));
    }
};

class C
{
public:
    key_value_pair makeProp()
    {
        value v = {{"property1", 1}, {"property2", {1, 2, 3}}};
        return object::value_type("C", std::move(v));
    }
};

class A
{
public:
    object makeProp()
    {
        B b;
        C c;

        object obj;
        obj["A"] = {b.makeProp(), c.makeProp()};
        return obj;
    }
};

int main()
{
    A a;
    std::cout << a.makeProp() << std::endl;

    return 0;
}

我希望这可以解释为什么我添加了辅助函数,并让我更清楚我想要实现的目标。

这将返回:

{
  "A": [
    [
      "B",
      [
        "property1",
        1
      ]
    ],
    [
      "C",
      {
        "property1": 1,
        "property2": [
          1,
          2,
          3
        ]
      }
    ]
  ]
}

虽然我预料到了:

{
  "A": {
    "B": {
      "property1": 1
    },
    "C": {
      "property1": 1,
      "property2": [
        1,
        2,
        3
      ]
    }
  }
}

最佳答案

makeObject 返回单个对象。您将它们作为初始化列表传递给 json::value,因此您应该期望 {makeObject(...), makeObject(...)} 创建数组:docs

If the initializer list consists of key/value pairs, an object is created. Otherwise an array is created.

相反,您想要创建键值对的初始值设定项列表,而不是对象:

#include <iostream>
#include <boost/json/src.hpp> // for COLIRU

namespace json = boost::json;

int main() {
    // construct:
    json::object obj{
        {"main",
         {
             {"test1", 123},
             {"test2", 456},
         }},
    };

    std::cout << obj << std::endl;

    // update:
    obj["main"] = {{"B", "someValue"}, {"C", "someOtherValue"}};
    std::cout << obj << std::endl;
}

查看Live On Coliru:

{"main":{"test1":123,"test2":456}}
{"main":{"B":"someValue","C":"someOtherValue"}}

奖金

如果您出于某种原因/需要/拥有辅助功能:

auto makeProp(std::string_view name, json::value v) {
    return json::object::value_type(name, std::move(v));
}

关于c++ - 将 JSON 对象作为 Boost 中的键值对插入现有 JSON 对象中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73784199/

相关文章:

c++ - 在 C++ 中操作 blob

json - VB.net JSON 反序列化

c++ - 帮我调试这个 - C++ Boost

c++ - Boost C++ 库是否支持 Sparc 上的 Solaris?

c++ - string::find() c++ 使用的字符串搜索算法

c++ - STL for_each 提示参数列表

javascript - JSON 中的嵌套键/值结构

boost - 使用 clang-tidy 处理大量与 boost 单元测试相关的警告

c++ - 将 Boost.asio 与 cmake 一起使用?

JSON-ISuperObject