【发布时间】:2018-01-03 20:15:11
【问题描述】:
我正在使用 C++ 中的 sstream 对 std::map 进行序列化。 序列化函数:
template <class key, class value>
std::string serializeMap(const std::map<key, value>& v){
std::stringstream ss;
std::for_each(v.begin(), v.end(), [&ss](const std::pair<key, value>& s){
ss.write ((char*)&s, sizeof(std::pair<key,value>));
});
return ss.str();
}
并使用此反序列化:
template <class key, class value>
void deSerializeMap(const std::string& s, std::map<key, value>& v){
std::stringstream ss1;
ss1<<s;
int pos = 0;
printf("\nlen %d\n", s.size());
while(ss1){
char* ar = new char[sizeof(std::pair<key, value>)];
ss1.read(ar, sizeof(std::pair<key, value>));
v.insert(*(reinterpret_cast<std::pair<key, value>*>(ar)));
pos+=sizeof(std::pair<key, value>);
ss1.seekg(pos);
delete[] ar;
}
}
使用std::string 可以按预期工作。我必须使用一个将const char* 作为参数的C 函数,我尝试使用c_str() 并添加一个
char 数组的 NULL 字符,但 strlen 给出零。我有什么遗漏吗?
【问题讨论】:
-
尝试分别写/读键和值。作为@user9169574,您无法使用 std::string 和 sizeof 获得对的大小
-
我会试试的。谢谢。
-
这里有很多问题,但基本上,如果您曾经为通用数据结构编写序列化代码,并且您没有在包含的类型上递归调用 serialize,那么就有问题了。您假设您的键和值是 POD 类型;在不必要的 pod 类型上调用 sizeof 是代码异味。另外,尽量不要在这样的代码中使用 new 和 delete;这也是代码气味(在非必要的 pod 类型上 reinterpret_cast 也是如此;你可以看到很多气味;-))。
-
您还应该使用类型的默认重载以使其可序列化:
template <typename Key, typename T> std::ostream& operator<<(std::ostream& os, const std::map<Key, T>& map);根据 C++ 重载实现序列化功能。然后,任何类型支持operator<<的地图也将被支持。它也适用于任何输出流,而不仅仅是字符串流。