Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何序列化/反序列化std::map<;int,MyObject>;与C+中的json之间的通信+;_C++_Json_C++11_Nlohmann Json - Fatal编程技术网

C++ 如何序列化/反序列化std::map<;int,MyObject>;与C+中的json之间的通信+;

C++ 如何序列化/反序列化std::map<;int,MyObject>;与C+中的json之间的通信+;,c++,json,c++11,nlohmann-json,C++,Json,C++11,Nlohmann Json,我正在尝试使用 它表示映射的键必须能够生成std::string。我怎样才能做到这一点 实现与自定义对象的转换的基本用法是: using nlohmann::json; namespace ns { void to_json(json& j, const MyObject& p) { j = json{{"name", p.name}, {"address", p.address}, {"age"

我正在尝试使用

它表示映射的键必须能够生成
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&p)
void from_json(const json&j,std::map&p)
。由于库已经支持
std::map
,它应该可以为我做一切,我只需要将
int
转换为
std::string
。我怎样才能做到这一点呢?

自述文件中的措辞清楚地说明了这一点不起作用的原因(重点是我的):

同样,任何关联键值容器。。。其键可以构造
std::string
,其值可以用于构造JSON值。。。可用于创建JSON对象

这就是为什么使用
int
作为键不适用于此库的原因;无法从
int
构造
std::string


自然的后续问题是为什么这是不允许的。这是你必须向图书馆的作者寻求明确答案的事情

我们可以推测这是因为没有一种方法可以将积分转换成字符串。也许假设一个不带前导零的10进制表示是一个合理的选择,但没有令人信服的理由说明这是唯一的选择

十六进制编码的字符串、科学记数法、数千个分隔符或任何可能的其他选项呢

另一个可能的原因是整数键表示稀疏数组,因此可能不清楚您是请求在输出中生成对象还是数组


一个可能的解决方案是构建一个助手,通过运行
std::to_string()
,将任何映射转换为
std::map

//复制变量
模板
映射到字符串键控映射(T常量和输入){
地图输出;
用于(自动常量和对:输入){
放置(std::to_字符串(pair.first),pair.second);
}
返回输出;
}
//移动变体
模板
映射到字符串键控映射(T&&input){
地图输出;
用于(自动配对:输入(&P){
emplace(std::to_string(pair.first),std::move(pair.second));
}
返回输出;
}

不熟悉该特定库,但一个特定的解决方法是为
int
值提供一个轻量级包装,该值还实现了
运算符std::string
。这似乎是一个奇怪的限制。根据文档,映射值为整数不是问题,它将序列化它们。我无法立即看出在json中使用
int
s作为映射/列表键的问题。文档中的关键措辞是“谁的键可以构造
std::string
”。没有接受
int
值的
std::string
构造函数,这就是它不起作用的原因。@SamVarshavchik值为整数不是问题,因为JSON具有本机数字类型。这种情况必须得到处理,才能使实施变得有意义。但是,对象键不能是整数;它们一定是弦。库作者显然选择要求键可以显式转换为<代码> STD::String ,但是在C++ <代码> int <代码>中没有显式转换为 STD::String 。把map转换成一对数字数组和[jSON格式的对象]不是更好吗?确实有人在不改变任何东西的情况下使这种行为起作用:但我不认为它对我的行为起作用
// 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;
}