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

使用Nlohmann JSON时std::array<unsigned char>序列化失败求助

解决Nlohmann JSON序列化std::array<unsigned char, SIZE>的构造函数匹配错误问题

Nlohmann JSON默认仅支持std::array<char, N>的序列化(将其视为字符串),但对std::array<unsigned char, N>没有内置处理逻辑,导致构造函数匹配失败。你可以通过自定义序列化/反序列化函数解决这个问题,无需使用reinterpret_cast或替换类型。

方法1:全局特化adl_serializer(通用所有std::array<unsigned char, N>)

这种方式会让所有std::array<unsigned char, N>类型都能被Nlohmann JSON自动处理,适合多个类用到该类型的场景:

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

using json = nlohmann::json;
constexpr size_t SIZE = 10;

// 为std::array<unsigned char, N>特化序列化逻辑
namespace nlohmann {
template <size_t N>
struct adl_serializer<std::array<unsigned char, N>> {
    // 序列化:将unsigned char数组转为字符串存入JSON
    static void to_json(json& j, const std::array<unsigned char, N>& arr) {
        j = std::string(arr.begin(), arr.end());
        // 若数组含非打印字节,建议转为JSON数值数组(更安全):
        // j = json(arr.begin(), arr.end());
    }

    // 反序列化:从JSON转回unsigned char数组
    static void from_json(const json& j, std::array<unsigned char, N>& arr) {
        std::string str = j.get<std::string>();
        std::copy(str.begin(), str.end(), arr.begin());
        // 对应JSON数值数组的反序列化:
        // std::copy(j.begin(), j.end(), arr.begin());
    }
};
} // namespace nlohmann

// 你的自定义Person类
class Person {
public:
    std::array<unsigned char, SIZE> name;
    int age;
};

// 测试代码
int main() {
    Person p;
    std::copy("Bob", "Bob" + 3, p.name.begin());
    p.age = 25;

    // 序列化Person到JSON
    json j = p;
    std::cout << j.dump(4) << std::endl;

    // 反序列化JSON到Person
    Person p2 = j.get<Person>();
    return 0;
}

方法2:为Person类单独实现序列化函数(仅针对当前类)

如果只需要在Person类中处理std::array<unsigned char, SIZE>,可以直接为Person编写to_json和from_json函数:

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

using json = nlohmann::json;
constexpr size_t SIZE = 10;

class Person {
public:
    std::array<unsigned char, SIZE> name;
    int age;
};

// 为Person自定义序列化
void to_json(json& j, const Person& p) {
    // 将unsigned char数组转为字符串存入JSON字段
    j["name"] = std::string(p.name.begin(), p.name.end());
    j["age"] = p.age;
    // 若需转为字节数组:
    // j["name"] = json(p.name.begin(), p.name.end());
}

// 为Person自定义反序列化
void from_json(const json& j, Person& p) {
    std::string name_str = j["name"].get<std::string>();
    std::copy(name_str.begin(), name_str.end(), p.name.begin());
    p.age = j["age"].get<int>();
    // 对应字节数组的反序列化:
    // std::copy(j["name"].begin(), j["name"].end(), p.name.begin());
}

// 测试代码
int main() {
    Person p;
    std::copy("Alice", "Alice" + 5, p.name.begin());
    p.age = 30;

    json j = p;
    std::cout << j.dump(4) << std::endl;

    Person p2 = j.get<Person>();
    return 0;
}

关键说明

  • 若你的unsigned char数组包含非ASCII/非打印字节,建议使用JSON数值数组的方式(注释中的代码),避免JSON字符串的编码问题。
  • 两种方法都遵循Nlohmann JSON的扩展规则,无需修改库源码,也不需要reinterpret_cast。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 00:42:39