You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用boost::json访问嵌套JSON报错,如何修复?

Boost.JSON解析嵌套对象报错"not a string"的修复方案

问题背景

给定JSON数据:

{
    "type": "test",
    "version": 1,
    "data": {
        "name": "omni",
        "id": "123",
        "value": 3
    }
}

尝试用以下C++函数处理时,在解析data字段时抛出异常:

void process_data(std::string type, std::string data)
{
        boost::json::value data = boost::json::parse(data); // 变量名重复,覆盖参数
        std::string name = json.at("name").as_string().c_str();
        std::string id = json.at("id").as_string().c_str();
        int value = json.at("value").as_int64();

        std::cout << "Message data content:" << std::endl;
        std::cout << "Name: " << name << std::endl;
        std::cout << "Id: " << id << std::endl;
        std::cout << "Value: " << value << std::endl;
}

void process_message(std::string payload)
{
        boost::json::value json = boost::json::parse(payload);
        std::string type = json.at("type").as_string().c_str();
        int version = json.at("version").as_int64();

        std::cout << "Message received:" << std::endl;
        std::cout << "Type: " << type << std::endl;
        std::cout << "Version: " << version << std::endl;

        std::string data = json.at("data").as_string().c_str(); // 报错行
        process_data(data); // 缺少type参数
}

抛出的错误信息:

terminate called after throwing an instance of 'boost::wrapexcept<std::invalid_argument>'
  what():  not a string
Aborted (core dumped)

错误原因

  1. 核心问题:JSON中的data是嵌套对象,而非字符串,代码中调用as_string()尝试将对象转为字符串,触发类型不匹配异常。
  2. 次要问题:
    • process_data函数中局部变量data与参数data重名,导致逻辑错误;
    • 调用process_data时未传入type参数,不符合函数签名要求;
    • as_int64()返回int64_t类型,直接赋值给int存在隐式类型转换风险。

修复步骤

方案一:直接传递JSON对象(推荐,效率更高)

  1. 修改process_data参数,直接接收boost::json::value对象,避免重复解析:
    void process_data(std::string type, boost::json::value const& data)
    {
            std::string name = data.at("name").as_string().c_str();
            std::string id = data.at("id").as_string().c_str();
            // 显式转换int64_t到int,确保类型安全
            int value = static_cast<int>(data.at("value").as_int64());
    
            std::cout << "Message data content:" << std::endl;
            std::cout << "Name: " << name << std::endl;
            std::cout << "Id: " << id << std::endl;
            std::cout << "Value: " << value << std::endl;
    }
    
  2. 在process_message中直接获取嵌套的data对象并传递:
    void process_message(std::string payload)
    {
            boost::json::value json = boost::json::parse(payload);
            std::string type = json.at("type").as_string().c_str();
            int version = static_cast<int>(json.at("version").as_int64());
    
            std::cout << "Message received:" << std::endl;
            std::cout << "Type: " << type << std::endl;
            std::cout << "Version: " << version << std::endl;
    
            // 直接获取data对象,无需转为字符串
            boost::json::value const& data = json.at("data");
            process_data(type, data);
    }
    

方案二:序列化JSON对象为字符串(仅在必须传递字符串时使用)

如果业务逻辑要求必须传递字符串,可将JSON对象序列化为字符串后再传递:

  1. 修改process_message中的代码:
    void process_message(std::string payload)
    {
            // ... 原有代码不变 ...
    
            // 将data对象序列化为字符串
            std::string data_str = boost::json::serialize(json.at("data"));
            process_data(type, data_str);
    }
    
  2. 修正process_data中的变量名重复问题:
    void process_data(std::string type, std::string data_str)
    {
            boost::json::value data = boost::json::parse(data_str);
            std::string name = data.at("name").as_string().c_str();
            std::string id = data.at("id").as_string().c_str();
            int value = static_cast<int>(data.at("value").as_int64());
    
            // ... 原有输出逻辑不变 ...
    }
    

内容的提问来源于stack exchange,提问作者Mendes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 01:09:58