如何解决使用nlohmann解析JSON到map时的类型错误?
问题排查:nlohmann JSON解析char键unordered_map报错[type_error.302]
错误原因
你的JSON对象键是字符串类型(如"a"),但目标容器std::unordered_map<char, std::vector<std::string>>的键是char类型。nlohmann/json库默认不支持字符串到char的自动转换,导致解析时类型匹配失败,抛出[type_error.302] type must be array but is object错误。
解决方案
方案1:手动遍历转换键类型
直接遍历JSON对象的键值对,将字符串键转为char后赋值给目标容器:
#include <iostream> #include <string> #include <vector> #include <unordered_map> #include <fstream> #include <nlohmann/json.hpp> using json = nlohmann::json; int main() { std::unordered_map<char, std::vector<std::string>> wordList; std::ifstream file("wordlist.json"); if (!file.is_open()) { throw std::runtime_error("Failed to open wordlist.json"); } json data; file >> data; // 遍历JSON对象,转换键类型 for (const auto& [key_str, value] : data.items()) { if (!key_str.empty()) { char key = key_str[0]; // 取字符串首字符作为char键 wordList[key] = value.get<std::vector<std::string>>(); } } // 验证结果 for (const auto& [key, words] : wordList) { std::cout << key << ": "; for (const auto& word : words) { std::cout << word << " "; } std::cout << "\n"; } }
方案2:自定义类型序列化规则
通过模板特化nlohmann的adl_serializer,让库支持直接将JSON解析为目标容器类型,后续可直接使用get方法:
#include <iostream> #include <string> #include <vector> #include <unordered_map> #include <fstream> #include <nlohmann/json.hpp> using json = nlohmann::json; // 自定义JSON到unordered_map<char, vector<string>>的转换规则 namespace nlohmann { template<> struct adl_serializer<std::unordered_map<char, std::vector<std::string>>> { static void from_json(const json& j, std::unordered_map<char, std::vector<std::string>>& map) { for (const auto& [key_str, value] : j.items()) { if (!key_str.empty()) { char key = key_str[0]; map[key] = value.get<std::vector<std::string>>(); } } } }; } int main() { std::unordered_map<char, std::vector<std::string>> wordList; std::ifstream file("wordlist.json"); if (!file.is_open()) { throw std::runtime_error("Failed to open wordlist.json"); } json data; file >> data; wordList = data.get<decltype(wordList)>(); // 直接解析 // 验证结果 for (const auto& [key, words] : wordList) { std::cout << key << ": "; for (const auto& word : words) { std::cout << word << " "; } std::cout << "\n"; } }
注意事项
如果JSON中存在多字符键(如"ab"),上述代码会取首字符作为键,若不符合预期,需添加额外逻辑(如抛出错误、过滤多字符键)。
内容的提问来源于stack exchange,提问作者Coder
相关产品推荐
相关产品推荐

