我一直在try 使用boost::json::object来存储具有多个值的JSON对象,然后根据需要修改值,但一直无法找到执行修改的方法,即使在查看了有关C++引用和重载方法的信息后也是如此,只是返回类型不同,这似乎是相关的.

在下面的测试代码中,我在boost::json::object中创建了一个简短的JSON对象,如"Quick Look" section of the Boost.JSON documentation所示,从其中读出并显示一个值,try 修改该值,然后读出并显示新值.

#include <iostream>
#include <boost/json/src.hpp>
#include <boost/json/object.hpp>
using std::cout;
using std::endl;

int main(int argc, char* argv[]) {

    boost::json::object testobj;

    testobj["properties"] = { { "timestamp", "Fri Jan  6 02:17:29 PM EST 2023"}, { "textDescription", "This is a Description"} };

    const boost::json::string& s = testobj.at("properties").at("textDescription").as_string();
    cout << s << endl;

    testobj.at("properties").at("textDescription").as_string() = "Hello, World!";   // ERROR

    boost::json::string t = testobj.at("properties").at("textDescription").as_string();
    cout << t << endl;
    
    return 0;
}

在标记的错误行,会生成以下错误.

error: passing ‘const boost::json::string’ as ‘this’ argument discards qualifiers [-fpermissive]
        testobj.at("properties").at("textDescription").as_string() = "Hello, World!";
                                                                     ^~~~~~~~~~~~~~~

根据the documentation for value::as_string,有两个重载的as_string()方法,一个返回string&,另一个返回string const&.大概,返回的string&将允许修改该值,但我不知道如何访问该方法的特定重载.我的理解是,如果实例化的类是常量,那么将使用常量重载,否则将使用非常量重载,但我的实例化是非常量的,但它不起作用.谁能指出我在这里做错了什么,或者提供一些关于修改boost::json::object中类似值的其他方法的指导?

请注意,我还try 获取一个非常数boost::json::string& s引用并为其分配一个新字符串,但编译器也抱怨过这一点.否则,如果将第return 0行之前的三行注释掉,则上面代码中的其他所有内容都会按预期工作,所以问题就出在错误行.

推荐答案

在版本Boost 1.80.0:https://github.com/boostorg/json/commit/95a6297480ec403ccc2cf17ff02476dc7614f60c中添加了非常量value::at重载

它解决了他们的issue #703个问题:

value::at()返回带有常量限定符的值,即使值为 非常数数据.

示例

value jv1 = {{"key", 1}};
auto& a1  = jv1.as_object().at("key");  // returns value&
auto& a2  = jv1.at("key");              // returns const value&
value& a3 = jv1.at("key");              // compile error

value jv2 = {1, 2, 3};
auto& b1  = jv2.as_array().at(0);       // returns value&
auto& b2  = jv2.at(0);                  // returns const value&
value& b3 = jv2.at(0);                  // compile error

注:value.at_pointer()没有这样的问题.它返回常数值&; 如果数据是常量限定的,则返回Value,否则返回&;.

Boost 1.79.0的解决方法:

这在Boost 1.79.0中有效:

if (auto p = testobj.if_contains("properties"))
    if (auto td = p->as_object().if_contains("textDescription"))
        td->as_string() = "Hello, World!";

或者甚至只是

testobj["properties"].as_object()["textDescription"] = "Even better?";

看它100

Json相关问答推荐

合并二维数组的Jolt表达式

当有嵌套数组而没有嵌套数组时,展平JSON

如何创建可由Gin序列化到json的排序键值映射?

Allof Indide的JSON模式之一

使用自定义类型在Golang中解析JSON数组

将PNG图像保存为Python中的JSON文件

JOLT转换以根据条件删除json对象

使用 JOLT 将日期格式转换为 JSON

shell解析json并循环输出组合变量

在 json 嵌入的 YAML 文件中 - 使用 Python 仅替换 json 值

如何使用 LINQ 在 C# 中重构对象?

如何使用 Swiftui 判断 JSON 是否缺少键值对

.NET 对象最灵活的序列化是什么,但实现起来很简单?

如何从 mysql 数据库构建 JSON 数组

将文件发送到 Rails JSON API

使用 Retrofit 解析动态密钥 Json 字符串

Jackson JSON序列化,通过级别定义避免递归

Sequelize - 如何仅返回数据库结果的 JSON 对象?

如何在 Java 中将 YAML 转换为 JSON?

jq:按属性分组和键