nlohmann::json与结构体之间的相互转换
时间: 2025-05-27 10:34:02 浏览: 39
### 使用 `nlohmann::json` 进行 C++ 结构体的序列化和反序列化
#### 1. 序列化 (C++ 结构体 → JSON)
通过定义 `to_json` 函数,可以将自定义结构体转换为 JSON 对象。以下是具体的实现:
```cpp
#include <iostream>
#include "nlohmann/json.hpp"
using json = nlohmann::json;
namespace example {
struct Person {
std::string name;
int age;
double score;
};
// 定义 to_json 方法用于序列化
void to_json(json& j, const Person& p) {
j = json{{"name", p.name}, {"age", p.age}, {"score", p.score}};
}
}
int main() {
example::Person person{"Alice", 30, 87.5};
json j = person; // 自动调用 to_json 方法完成序列化
std::cout << j.dump(4) << std::endl; // 输出格式化的 JSON 字符串
}
```
此代码展示了如何利用 `to_json` 将 `example::Person` 类型的对象转化为 JSON 表达形式[^1]。
---
#### 2. 反序列化 (JSON → C++ 结构体)
为了支持从 JSON 到 C++ 结构体的转换,需提供 `from_json` 函数。下面是一个完整的例子:
```cpp
#include <iostream>
#include "nlohmann/json.hpp"
using json = nlohmann::json;
namespace example {
struct Person {
std::string name;
int age;
double score;
};
// 定义 from_json 方法用于反序列化
void from_json(const json& j, Person& p) {
j.at("name").get_to(p.name);
j.at("age").get_to(p.age);
j.at("score").get_to(p.score);
}
}
int main() {
json j = R"(
{
"name": "Bob",
"age": 25,
"score": 92.3
})"_json;
example::Person person;
j.get_to(person); // 调用 from_json 实现反序列化
std::cout << "Name: " << person.name << "\n";
std::cout << "Age: " << person.age << "\n";
std::cout << "Score: " << person.score << "\n";
}
```
这段代码演示了如何通过 `from_json` 方法解析 JSON 并填充到指定的 C++ 结构体实例中[^4]。
---
#### 3. 更简洁的方式:使用宏简化操作
如果不想手动编写 `to_json` 和 `from_json`,可以通过 `NLOHMANN_DEFINE_TYPE_INTRUSIVE` 或 `NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE` 来快速实现序列化/反序列化逻辑。例如:
```cpp
#include <iostream>
#include "nlohmann/json.hpp"
using json = nlohmann::json;
struct People {
std::string name;
int age;
std::string sex;
int height;
// 使用宏自动绑定字段
NLOHMANN_DEFINE_TYPE_INTRUSIVE(People, name, age, sex, height);
};
int main() {
People people{"John Doe", 30, "male", 180};
json json_obj = people; // 自动序列化
std::cout << "Serialized:\n" << json_obj.dump(4) << "\n";
// 测试反序列化
json input_data = R"({
"name": "Jane Smith",
"age": 28,
"sex": "female",
"height": 165
})"_json;
People deserialized_people = input_data; // 自动反序列化
std::cout << "Deserialized Name: " << deserialized_people.name << "\n";
}
```
这种方式显著减少了重复代码量,并提高了开发效率[^2]。
---
#### 注意事项
- **异常处理**:在实际应用中应考虑捕获可能抛出的异常(如键不存在或类型不匹配),并采取适当措施。
- **命名空间管理**:当涉及多个命名空间时,确保 `to_json` 和 `from_json` 的声明位于目标类所在的相同命名空间下。
- **性能优化**:对于大规模数据集,评估不同方法间的性能差异以便选取最优方案。
---
阅读全文
相关推荐




















