MALOUDA-PSA 2024-03-11 07:53 采纳率: 91%
浏览 6
已结题

Nlohamann的from_json问题2


#include <nlohmann/json.hpp>
using json = nlohmann::json;
// 假设这是MenuItem类的定义
class MenuItem {
public:
    std::string name;
    std::vector<MenuItem> children;
};
namespace nlohmann {
template <>
void from_json(const json& j, MenuItem& item) {
    j.at("name").get_to(item.name);
    // 反序列化子菜单项
    for (const auto& childJson : j.at("children")) {
        MenuItem childItem;
        from_json(childJson, childItem);  // 调用当前重载的from_json函数
        item.children.push_back(childItem);
    }
}
} // namespace nlohmann
int main() {
    // 示例JSON字符串
    const std::string jsonString = R"({
        "name": "Parent",
        "children": [
            {"name": "Child1"},
            {"name": "Child2"}
        ]
    })";
    // 反序列化示例
    json j = json::parse(jsonString);
    MenuItem rootItem;
    from_json(j, rootItem);  // 此处会调用上面重载的from_json函数
    return 0;
}

编译报错: no function template matches function template specialization from_json

  • 写回答

3条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-03-11 07:53
    关注

    引自免费微信小程序:皆我百晓生

    在Nlohmann的JSON库中,当您尝试为自定义类型MenuItem从JSON反序列化时,遇到编译错误指出没有匹配的模板函数。针对这个问题,请确保以下几点:

    1. 包含必要的头文件:确保在使用nlohmann/json.hpp之外,还正确地在需要的地方包含了MenuItem类的定义。

    2. 模板特殊化的可见性:由于您将from_json模板特殊化放在了全局作用域内,而不是在MenuItem类内部或其关联命名空间内,所以要确保该特殊化在调用处是可见的。如果MenuItem是在其他文件中定义的,请将此模板特殊化代码置于与MenuItem定义相同的命名空间或在包含MenuItem定义的头文件末尾添加此模板特殊化。

    3. 检查JSON键是否存在:在访问"children"数组之前,可以先检查键是否存在以避免潜在的运行时错误。

    修正后的代码(假设MenuItem类已经正确声明):

    #include <nlohmann/json.hpp>
    using json = nlohmann::json;
    
    // 假设这是MenuItem类的定义,这里仅作示意
    class MenuItem {
    public:
        std::string name;
        std::vector<MenuItem> children;
    };
    
    // 将模板特殊化放在 MenuItem 类所在的命名空间内(如果适用)
    namespace MenuItemNamespace { // 请替换为实际的 MenuItem 命名空间
    
    // 如果 MenuItem 是全局作用域内的,则无需额外的命名空间
    
    template <>
    void nlohmann::from_json(const json& j, MenuItem& item) {
        if (j.contains("name")) {
            j.at("name").get_to(item.name);
        }
    
        // 检查并反序列化子菜单项
        if (j.contains("children") && j["children"].is_array()) {
            for (const auto& childJson : j.at("children")) {
                MenuItem childItem;
                from_json(childJson, childItem);  // 调用当前重载的from_json函数
                item.children.push_back(childItem);
            }
        }
    }
    
    } // namespace MenuItemNamespace 或 全局作用域结束
    
    int main() {
        const std::string jsonString = R"({
            "name": "Parent",
            "children": [
                {"name": "Child1"},
                {"name": "Child2"}
            ]
        })";
    
        json j = json::parse(jsonString);
        MenuItem rootItem;
        from_json(j, rootItem);  // 此处会调用上面重载的from_json函数
        return 0;
    }
    

    经过上述检查和调整后,编译错误应能得以解决。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 3月22日
  • 已采纳回答 3月14日
  • 创建了问题 3月11日

悬赏问题

  • ¥15 echarts动画效果失效的问题。官网下载的例子。
  • ¥60 许可证msc licensing软件报错显示已有相同版本软件,但是下一步显示无法读取日志目录。
  • ¥15 Attention is all you need 的代码运行
  • ¥15 一个服务器已经有一个系统了如果用usb再装一个系统,原来的系统会被覆盖掉吗
  • ¥15 使用esm_msa1_t12_100M_UR50S蛋白质语言模型进行零样本预测时,终端显示出了sequence handled的进度条,但是并不出结果就自动终止回到命令提示行了是怎么回事:
  • ¥15 前置放大电路与功率放大电路相连放大倍数出现问题
  • ¥30 关于<main>标签页面跳转的问题
  • ¥80 部署运行web自动化项目
  • ¥15 腾讯云如何建立同一个项目中物模型之间的联系
  • ¥30 VMware 云桌面水印如何添加