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

如何用nlohmann/json序列化/反序列化std::map<int, MyObject>?仅转int键为string

用nlohmann/json序列化std::map<int, MyObject>的正确姿势

嘿,这个问题我之前也踩过坑!其实你完全不用手动实现std::map<int, MyObject>的to_json和from_json函数——nlohmann/json库原生就支持std::map的序列化/反序列化,只要满足两个简单条件:

  • 你的MyObject类型已经正确实现了对应的序列化函数(你已经写好了,重点是要把这些函数放在和MyObject同一个命名空间里,这样库才能通过ADL(参数依赖查找)找到它们)
  • map的键类型(这里是int)能被转换为std::string——而int是库默认支持的类型,会自动用std::to_string转成字符串键,根本不用你额外写代码!

直接能用的示例代码

先给你一段可以直接跑的完整代码,验证一下:

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

using nlohmann::json;

namespace ns {
// 你的自定义对象
struct MyObject {
    std::string name;
    std::string address;
    int age;
};

// 序列化函数,必须和MyObject同命名空间!
void to_json(json& j, const MyObject& p) {
    j = json{{"name", p.name}, {"address", p.address}, {"age", p.age}};
}

// 反序列化函数,同样要在同命名空间
void from_json(const json& j, MyObject& p) {
    j.at("name").get_to(p.name);
    j.at("address").get_to(p.address);
    j.at("age").get_to(p.age);
}
} // namespace ns

int main() {
    // 构建测试用的map
    std::map<int, ns::MyObject> user_map;
    user_map[1] = {"Alice", "123 Main St", 30};
    user_map[2] = {"Bob", "456 Oak Ave", 25};

    // 直接序列化,库会自动处理int键转string和MyObject的序列化
    json j = user_map;
    // 格式化输出JSON,你会看到键是"1"、"2"这样的字符串
    std::cout << j.dump(4) << std::endl;

    // 反序列化也一样简单
    std::map<int, ns::MyObject> restored_map = j.get<std::map<int, ns::MyObject>>();
    return 0;
}

运行这段代码后,输出的JSON会是这样的:

{
    "1": {
        "name": "Alice",
        "address": "123 Main St",
        "age": 30
    },
    "2": {
        "name": "Bob",
        "address": "456 Oak Ave",
        "age": 25
    }
}

如果你想自定义int键的格式

要是你不想用默认的数字字符串(比如想给键加个前缀,变成"user_1"、"user_2"),那可以通过特化库的key_access结构体来实现自定义转换:

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

namespace nlohmann::detail {
// 特化int类型的键访问逻辑
template <>
struct key_access<int> {
    // 序列化时把int转成自定义格式的字符串
    static void to_json(json& j, const int& key) {
        j = "user_" + std::to_string(key);
    }

    // 反序列化时从自定义字符串还原int
    static void from_json(const json& j, int& key) {
        std::string key_str = j.get<std::string>();
        // 去掉前缀"user_",还原数字
        if (key_str.starts_with("user_")) {
            key = std::stoi(key_str.substr(5));
        } else {
            throw json::parse_error(0, "Invalid key format: expected 'user_*'");
        }
    }
};
} // namespace nlohmann::detail

加了这段代码后,序列化出来的键就会变成"user_1"、"user_2",反序列化时也能正确把这些字符串转回到int键。

最关键的注意事项

  • 一定要把MyObject的to_json和from_json函数放在和MyObject同一个命名空间里,不然库找不到这些函数,会导致序列化失败。
  • 只要用默认的int转string,完全不需要额外写任何代码,库会自动处理map的序列化/反序列化。
  • 只有当你需要自定义键的格式时,才需要特化key_access或者写自定义转换逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 23:32:42