我有一个如下所示的类层次结构:类 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;
}
{"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/