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

nlohmann::json如何实现支持多键深层取值的通用get函数

实现方案

核心思路

基于C可变参数模板实现任意层数的嵌套JSON取值,逐层向下访问节点,兼容任意数量的键参数输入。以下分别提供C17(更简洁)和C++11兼容版本的实现。

C++17 折叠表达式实现(推荐)

直接利用C++17的折叠表达式语法简化逐层取值逻辑,无需递归:

#include <nlohmann/json.hpp>
#include <string>
#include <fstream>
#include <iostream>
#include <utility>

using json = nlohmann::json;

class My_config {
public:
    My_config(const std::string config_path) {
        std::ifstream ifs(config_path);
        if (ifs.is_open()) {
            file_content = json::parse(ifs);
            ifs.close();
        }
    }

    // 可变参数通用get函数
    template<typename... Keys>
    json get(const std::string& first_key, Keys&&... rest_keys) {
        json current = file_content[first_key];
        // 折叠表达式依次应用剩余所有键
        ((current = current[std::forward<Keys>(rest_keys)]), ...);
        return current;
    }

private:
    json file_content;
};

int main() {
    auto my_conf = My_config("../test.json");

    std::cout << "Get happy : " << my_conf.get("happy") << std::endl;
    // 两层嵌套取值
    std::cout << "Get [answer][everything] : " << my_conf.get("answer", "everything") << std::endl;
    // 支持更多层,比如三层嵌套可直接写my_conf.get("a","b","c")
    return 0;
}

C++11 兼容递归实现

如果使用C++11标准,可通过递归可变参数模板实现相同效果:

#include <nlohmann/json.hpp>
#include <string>
#include <fstream>
#include <iostream>

using json = nlohmann::json;

class My_config {
public:
    My_config(const std::string config_path) {
        std::ifstream ifs(config_path);
        if (ifs.is_open()) {
            file_content = json::parse(ifs);
            ifs.close();
        }
    }

    // 单键取值(递归终止条件)
    json get(const std::string& key) {
        return file_content[key];
    }

    // 多键递归取值
    template<typename... RestKeys>
    json get(const std::string& first_key, RestKeys... rest_keys) {
        return get_impl(file_content[first_key], rest_keys...);
    }

private:
    json file_content;

    // 递归终止:最后一层键
    json get_impl(const json& current, const std::string& key) {
        return current[key];
    }

    // 递归逐层访问
    template<typename... RestKeys>
    json get_impl(const json& current, const std::string& key, RestKeys... rest_keys) {
        return get_impl(current[key], rest_keys...);
    }
};

int main() {
    auto my_conf = My_config("../test.json");

    std::cout << "Get happy : " << my_conf.get("happy") << std::endl;
    std::cout << "Get [answer][everything] : " << my_conf.get("answer", "everything") << std::endl;
    return 0;
}

运行结果

测试用test.json的输出如下:

Get happy : true
Get [answer][everything] : 42

可选优化点

  • 异常处理:默认情况下如果路径中某层键不存在,nlohmann/json会抛出nlohmann::json::out_of_range异常,可在get函数中添加contains判断,不存在时返回默认值或自定义异常。
  • 数组支持:如果需要支持JSON数组的下标取值,可将参数类型调整为std::variant<std::string, size_t>适配字符串键和整数索引的混合路径。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 22:36:02