问题描述
我正在尝试使用https://github.com/nlohmann/json对std::map<int,MyObject>
进行序列化/反序列化
它告诉here,该地图的键必须能够生成std::string
。我该如何实现?
using nlohmann::json;
namespace ns {
void to_json(json& j,const MyObject& p) {
j = json{{"name",p.name},{"address",p.address},{"age",p.age}};
}
void from_json(const json& j,MyObject& p) {
j.at("name").get_to(p.name);
j.at("address").get_to(p.address);
j.at("age").get_to(p.age);
}
} // namespace ns
但是我应该为地图做什么?我要做的最后一件事是实现void to_json(json& j,const std::map<int,MyObject>& p)
和void from_json(const json& j,std::map<int,MyObject>& p)
。由于该库已经支持std::map
,所以它应该为我做所有事情,我只需要将int
转换为std::string
。我该怎么办?
解决方法
自述文件中的措词很清楚,为什么它不起作用(强调我的意思):
同样,任何关联的键值容器...其键可以构造一个
std::string
,并且其值可用于构造JSON值...可用于创建一个JSON对象。
这就是为什么使用int
作为键对此库不起作用的原因; std::string
不能从int
构造。
自然的后续问题是为什么。这是您必须向库的作者要求的明确答案。
我们可以推测是因为没有一种将整数转换为字符串的方法。也许假设以10为基数的表示形式不包含前导零将是一个合理的选择,但没有令人信服的理由为什么这必须是唯一的选择。
十六进制编码的字符串,科学计数法,数千个分隔符或任何其他可能的其他选项呢?
另一个可能的原因是整数键建议使用稀疏数组,因此可能不清楚您是要在输出中生成对象还是要生成数组。
一种可能的解决方案是构建一个助手,该助手通过通过std::map<std::string,TValue>
运行键来将任何映射转换为std::to_string()
:
// Copy variant
template <typename T>
std::map<std::string,typename T::mapped_type> to_string_keyed_map(T const & input) {
std::map<std::string,typename T::mapped_type> output;
for (auto const & pair : input) {
output.emplace(std::to_string(pair.first),pair.second);
}
return output;
}
// Move variant
template <typename T>
std::map<std::string,typename T::mapped_type> to_string_keyed_map(T && input) {
std::map<std::string,typename T::mapped_type> output;
for (auto & pair : input) {
output.emplace(std::to_string(pair.first),std::move(pair.second));
}
return output;
}