使用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
相关产品推荐
相关产品推荐

