首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用sstream序列化std::map

使用sstream序列化std::map
EN

Stack Overflow用户
提问于 2018-01-04 04:15:12
回答 1查看 847关注 0票数 0

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

代码语言:javascript
复制
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();
}

并使用以下代码进行反序列化:

代码语言:javascript
复制
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数组中,但strlen给出的值为零。我是不是漏掉了什么?

EN

回答 1

Stack Overflow用户

发布于 2018-01-07 07:58:19

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

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

要实现您想要的功能,一个简单的方法是使用如下所示的函数模板:

代码语言:javascript
复制
template <typename T>
uint64_t write(const T& t);

write函数通常返回序列化的字节数的无符号整数。这个模板化函数应该专门用于所有POD和您希望序列化的任何非POD类型。所以在你的例子中,除了intfloatdoublechar等等。您需要对映射进行遍历并对每个键值对调用writewrite(const std::map<K,T>& m)。此外,对于序列化,通常在实际数据之前编写一个头,以便可以反序列化数据(例如,如何知道映射包含多少元素?)。

幸运的是(也许)对您来说,标准库有这样一个模式(请参阅“装饰器”模式),正如@ Alexander Huszagh所提到的,那就是流运算符(operator<<),它可以在任何POD类型上调用,所以序列化std::map的(简单而简单的)方法是:

代码语言:javascript
复制
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;
}

上面的代码将很难反序列化,因为递归调用可能只需要一个数字、字符或字符串(带新行),而不会添加我添加的"header“,但是您的代码似乎假设它知道KeyValue模板参数,所以它可能对您没问题。

无论如何,你不应该尝试自己编写序列化程序,这是一项艰巨的工作,使其正确和通用,也是完全浪费时间,因为在web上有很多公开可用的。既然您对序列化映射感兴趣,我建议您使用一些JSON库。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48084507

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档