nlohmann/json支持直接赋值转换vector,只需确保元素类型可构造(如int、string或已定义from_json的结构体),避免手动循环、强制转换或重复parse。

用 nlohmann/json 直接赋值转换最省事
只要你的 std::vector 元素类型支持从 json 构造(比如 int、std::string、或自定义结构体加了 from_json),nlohmann/json 库能自动完成数组到 vector 的整批转换,不用手写循环。
常见错误是试图用 json::array() 强制转换,或者对每个元素手动调用 at(i).get<t>()</t> —— 这既慢又容易越界。正确做法是让库自己推导:
json j = "[1, 2, 3, 4]"_json; std::vector<int> v = j; // ✅ 一行搞定,内部按需遍历+构造
- 确保
j.is_array()为 true,否则运行时抛json::type_error - 如果元素类型复杂(如嵌套结构体),必须提前定义
void from_json(const json&, YourStruct&) - 不建议用
j.get<:vector>>()</:vector>,它会做一次完整拷贝;直接赋值利用移动语义更高效
自定义结构体转 vector 时 missing from_json 是最常见崩溃点
nlohmann/json 不会自动反射字段,没配 from_json 就调 json::get<yourstruct>()</yourstruct>,会直接 throw json::type_error: cannot use get() with null(即使 JSON 非空)。
示例中漏掉 from_json 定义,下面这行就会崩:
立即学习“C++免费学习笔记(深入)”;
struct Person { std::string name; int age; };
std::vector<Person> people = j; // ❌ 崩在这里,除非已定义 from_json
- 必须在命名空间内(通常是
namespace nlohmann)特化from_json函数 - 字段名要和 JSON key 完全一致(区分大小写),且不能有缺失字段(除非用
value()提供默认值) - 别在
from_json里 throw 自定义异常——nlohmann 只捕获自己类型的异常,否则程序 abort
大数组下避免重复解析:先 parse 再复用 json 对象
如果同一段 JSON 字符串要转多个 vector(比如不同字段拆成不同 vector),千万别反复调 json::parse(str)。每次 parse 都触发完整语法分析和内存分配,性能损耗明显。
正确做法是 parse 一次,然后用路径访问或迭代子节点:
json root = json::parse(json_str); // ✅ 一次解析 auto ids = root["items"].get<std::vector<int>>(); // ✅ 复用 root auto names = root["items"].get<std::vector<std::string>>(); // ✅ 同样复用
- 如果 JSON 很大但只取其中几个数组,用
root.at("path").is_array()做存在性检查,比 try/catch 更轻量 - 不要用
root["missing_key"]访问可能不存在的 key——它会静默创建 null 节点,后续get<vector></vector>必崩 - 用
root.value("key", default_val)替代at()+ 默认逻辑,更简洁安全
用 emplace_back 手动转换仅在特殊场景需要
只有当你需要在转换过程中过滤、映射、或做类型预处理(比如把字符串数字转 int 并跳过非法项),才该放弃自动转换,改用手动循环 + emplace_back。
注意:手动转换时别用 push_back(T{}) 再赋值,浪费构造;也别在循环里反复调 json.size()(它不是 O(1)):
std::vector<int> v;
v.reserve(j.size()); // ✅ 预分配避免 realloc
for (const auto& item : j) {
if (item.is_number()) v.emplace_back(item.get<int>()); // ✅ 直接构造
}
- 如果 JSON 数组含混合类型(如
[1, "2", 3.0]),item.get<int>()</int>会 throw,务必加is_number_integer()判断 - 用 range-based for 遍历比下标访问快,因为 nlohmann 的
operator[]有边界检查开销 - 别在循环里做字符串 split 或正则——那已经超出 JSON 转换范畴,应前置清洗
from_json 必须显式定义,或者在大 JSON 场景下无意识重复 parse。



















