使用sstream序列化std :: map

时间:2018-01-03 20:15:12

标签: c++ c++11 sstream

我正在使用C ++中的sstream序列化std :: map。 序列化功能:

kubectl

使用这个反序列化:

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为参数的C函数,我尝试使用const char*并添加一个 char数组为NULL字符,但c_str()为零。我有什么遗失的吗?

1 个答案:

答案 0 :(得分:1)

正如@Nir Friedman所提到的,如果你正在实现一个序列化程序而不是在容器的元素上调用它recursivley,那么你可能做错了。

进行这样的递归序列化意味着将POD类型作为“atoms”(递归结束条件),递归步骤是在非POD类型的每个成员上调用序列化器。

实现目标的简单方法是使用以下函数模板:

template <typename T>
uint64_t write(const T& t);

write函数通常返回一个无符号整数,表示序列化了多少字节。此模板化功能应专用于所有POD和您希望序列化的任何非POD类型。因此,除了intfloatdoublechar等之外,您还需要write(const std::map<K,T>& m)覆盖地图和每个密钥 - 值对,调用write。通常对于序列化,您在实际数据之前编写一个标题,以便您可以反序列化数据(例如,您如何知道地图包含多少元素?)。

幸运的是(也许),标准库有@ Alexander Huszagh提到的这种模式(参见“装饰器”模式),这就是可以调用的流操作符(operator<<)任何POD类型,所以序列化std::map的(天真且简单的)方法是:

template<typename K, typename V>
std::ostream& operator<<(std::ostream& os, const std::map<K,V>& m)
{
    os << "map" << '\n';             //write the type
    os << m.size() << '\n'; //write the size of the data
    for(auto&& kvp : m)
    {
        os << "pair" << '\n';
        os << kvp.first << '\n';  //Recursive call here...
        os << kvp.second << '\n'; //Recursive call here...
    }
    return os;
}

上面的反序列化会很复杂,因为递归调用可能只是一个数字,字符串或一个字符串(带有新行),它不会添加我添加的“标题”,但是你的代码似乎认为它知道了KeyValue模板参数,因此可能适合您。

无论如何,你不应该自己尝试编写一个序列化程序,要使其正确和通用,并且完全浪费时间是很困难的,因为网上有很多可公开的。 由于您对序列化地图感兴趣,我建议使用一些JSON库。