带explicit构造函数的structA使用nlohmann JSON反序列化报错排查
带explicit构造函数结构体的nlohmann JSON反序列化问题解决
问题背景
定义了带explicit构造函数的结构体及对应的JSON序列化/反序列化函数:
struct structA { explicit structA(const std::size_t num) : a(num) {} std::vector<structB> a; glm::quat b; glm::vec3 c; glm::vec3 d{1.0f}; }; // 序列化函数 inline void to_json(json& j, const structA& t) { j = {{"a", t.a}, {"b", t.b}, {"c", t.c}, {"d", t.d}}; } // 反序列化函数 inline void from_json(const json& j, structA& t) { j.at("a").get_to(t.a); j.at("b").get_to(t.b); j.at("c").get_to(t.c); j.at("d").get_to(t.d); }
序列化功能正常,但反序列化时尝试传入构造参数调用get方法:
const auto& structAVal = frameJson["structA"].get<structA>(21);
出现编译错误:
include/nlohmann_json/nlohmann/json.hpp:19336:16: note: candidate function template not viable: requires 0 arguments, but 1 was provided basic_json get() const include/nlohmann_json/nlohmann/json.hpp:19336:16: note: candidate function template not viable: requires 0 arguments, but 1 was provided BasicJsonType get() const include/nlohmann_json/nlohmann/json.hpp:19336:16: note: candidate function template not viable: requires 0 arguments, but 1 was provided ValueType get() const noexcept(noexcept(
不传入参数则报错“需1个参数,提供0个”,陷入两难。
问题原因
- nlohmann JSON的
get<T>()方法没有接收构造参数的重载,无法通过get<structA>(21)传递构造参数。 structA没有无参构造函数,直接调用get<structA>()时,库无法默认构造实例供from_json填充。from_json的设计逻辑是接收已存在的对象引用,再将JSON数据赋值给它,不需要外部传入构造参数。
解决方案
方案1:先构造对象,再填充数据
手动构造structA实例,再调用get_to方法完成反序列化:
// 先传入构造参数创建实例 structA structAVal(21); // 将JSON数据填充到已有的对象中 frameJson["structA"].get_to(structAVal);
方案2:为structA添加无参构造能力
如果业务允许,可给structA添加无参构造函数,或给现有构造参数设置默认值:
struct structA { // 方式A:显式默认无参构造 structA() = default; explicit structA(const std::size_t num) : a(num) {} // 方式B:给构造参数设置默认值(二选一即可) // explicit structA(const std::size_t num = 0) : a(num) {} std::vector<structB> a; glm::quat b; glm::vec3 c; glm::vec3 d{1.0f}; };
修改后即可直接使用get<structA>():
const auto& structAVal = frameJson["structA"].get<structA>();
内容的提问来源于stack exchange,提问作者Nitron_707
相关产品推荐
相关产品推荐

