【问题标题】:Serialization of STL unordered_mapSTL unordered_map 的序列化
【发布时间】:2012-12-14 12:22:33
【问题描述】:

我有一个程序使用具有此定义的无序映射:

unordered_map<const char*, vector<pair<int, int> >, function<unsigned int (const char *str)> > myMap(30000, hashing);

其中散列是一个用于散列键的函数。我的问题是 -> 如何序列化这种结构并在之后反序列化它?我真的需要这样,并且尽可能快速高效。我一直在阅读有关 boost 库的信息,但我不太了解如何将它们与这类东西一起使用。我知道有一些用于无序映射的 boost 库,但是,显然我做错了,编译器会抛出很多错误。有人可以给我一个关于如何序列化它的示例代码吗?谢谢。

【问题讨论】:

    标签: c++ serialization boost unordered-map


    【解决方案1】:

    TL;DR您不能序列化std::function,请改用常规谓词类。


    序列化地图(无论何种类型)很容易。本质上是:

    typedef std::map<std::string, std::string> Map;
    
    void serialize(Serializer& out, Map const& map) {
        out << map.size();
        for (auto const& p: map) { out << p.first << p.second; }
    }
    
    Map deserialize(Deserializer& in) {
        Map map;
    
        size_t size = 0;
        in >> size;
    
        for (size_t i = 0; i != size; ++i) {
            Map::key_type key;
            Map::mapped_type value;
            in >> key >> value;
            map[key] = value;
        }
    
        return map;
    }
    

    除了在一般情况下比较器和分配器都可以是有状态的吗?

    void serialize(Serializer& out, Map const& map) {
    +   out << map.value_compare() << map.get_allocator();
    
        out << map.size();
        for (auto const& p: map) { out << p.first << p.second; }
    }
    
    Map deserialize(Deserializer& in) {
    +   Map::key_compare comparator;
    +   Map::allocator_type allocator;
    +
    +   in >> comparator >> allocator;
    +
    +   Map map(comparator, allocator)
    
        size_t size = 0;
        in >> size;
        for (size_t i = 0; i != size; ++i) {
            Map::key_type key;
            Map::mapped_type value;
            in >> key >> value;
            map[key] = value;
        }
    
        return map;
    }
    

    那么,在你的情况下,假设 Boost.Serialization 知道如何处理 std::allocator(它是无状态的),它应该如何序列化 std::function&lt;unsigned int(char const*)&gt;

    回答:这是不可能的,因为std::function 执行类型擦除,这与 C++ 静态类型的性质(以及它缺乏内省)相冲突。一旦一个类型被删除,通常就不可能恢复它。

    您需要比较器的类型在map 的类型中显式 或具有查找它的外部手段。在任何情况下,可能很难将其放入 Boost.Serialization(无上下文)中。使用常规谓词类可能会更好。

    【讨论】:

    • in &gt;&gt; key &gt;&gt; value 不能用于任意字符串
    • @JonathanWakely:使用Boost.Serialization 肯定可以开箱即用。使用长度前缀还是转义取决于实现者。
    • 噢,对不起,我错过了你写信给Serializer而不是ostream!那么它确实有效。
    • 关于类型擦除的一点注意事项:它本身并没有使这成为不可能,只是 std::function 会这样做,因为它会擦除除对象的“可调用性”之外的所有内容。如果你有一个保留可调用性和可序列化性的类型擦除类型,它会起作用!
    • @ltjax:你当然是对的,这就是我试图用 一般而言来传达的意思我>;显然,如果该类型是专门为允许它而设计的(这通常是一种特殊的自省机制),那么它是可能的。
    猜你喜欢
    • 2011-05-16
    • 2011-05-24
    • 2014-08-04
    • 2014-09-27
    • 2016-01-24
    • 1970-01-01
    • 1970-01-01
    • 2013-01-17
    • 2010-12-15
    相关资源
    最近更新 更多