繁体   English   中英

如何序列化boost :: dynamic_bitset?

[英]How to serialize boost::dynamic_bitset?

如何使用boost :: dynamic_bitset成员序列化一个类?

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/dynamic_bitset.hpp>
#include <boost/serialization/bitset.hpp>
#include <sstream>

class A
{
    friend class boost::serialization::access;
    boost::dynamic_bitset<> x;
    template<class Archive>
    void serialize(Archive & ar, const unsigned int){
        ar & x;
    }
};

int main()
{
    A a;
    std::stringstream ss;
    boost::archive::text_oarchive oa(ss);
    oa << a;
    return 0;
}

编译给出错误(提升1.57)

In file included from /usr/include/boost/serialization/extended_type_info_typeid.hpp:37:0,
                 from /usr/include/boost/archive/detail/oserializer.hpp:38,
                 from /usr/include/boost/archive/detail/interface_oarchive.hpp:23,
                 from /usr/include/boost/archive/detail/common_oarchive.hpp:22,
                 from /usr/include/boost/archive/basic_text_oarchive.hpp:32,
                 from /usr/include/boost/archive/text_oarchive.hpp:31,
                 from dynamic_bitset_setial.cpp:1:
/usr/include/boost/serialization/access.hpp: In static member function ‘static void boost::serialization::access::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = boost::dynamic_bitset<>]’:
/usr/include/boost/serialization/serialization.hpp:69:5:   instantiated from ‘void boost::serialization::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = boost::dynamic_bitset<>]’
/usr/include/boost/serialization/serialization.hpp:128:9:   instantiated from ‘void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = boost::dynamic_bitset<>]’
/usr/include/boost/archive/detail/oserializer.hpp:148:5:   instantiated from ‘void boost::archive::detail::oserializer<Archive, T>::save_object_data(boost::archive::detail::basic_oarchive&, const void*) const [with Archive = boost::archive::text_oarchive, T = boost::dynamic_bitset<>]’
dynamic_bitset_setial.cpp:25:1:   instantiated from here
/usr/include/boost/serialization/access.hpp:118:9: error: ‘class boost::dynamic_bitset<>’ has no member named ‘serialize’

我继续提交了pull请求 ,为Boost Dynamic Bitset添加了Serialization支持

使用公共接口的序列化不是最佳的,因为to_block_range() / from_block_range()需要复制m_bits (以及后续的resize() )。

我在Boost Dynamic Bitset中添加了一个通用实现。 这些更改与开发或主控(1_58_0)完全合并。

变化

实施增加了

  • 最小的侵入性,只有一个嵌套的朋友( class serialization_impl; )已被向前声明为“key-hole”所需的朋友访问权限
  • 此类以及Boost Serialization的实际ADL挂钩在单独的头文件中实现( dynamic_bitset/serialization.hpp ,类似于具有序列化支持的其他boost库)。
  • 这意味着除非实际包含boost/dynamic_bitset/serialization.hpp否则存在对Boost Serialization内容的零依赖性
  • 实现零拷贝(利用Boost序列化中的std::vector<Block>的内置支持)

测试

pull请求中的第二次提交会为此功能添加测试。 我不确定如何将dyn_bitset_unit_tests5.cpp添加到Jamfile中。 我想必须采取其他措施来确保链接到Boost System和Boost Serialization。 我使用一个简单的包装器自己运行测试:

 #include <modular-boost/libs/dynamic_bitset/dyn_bitset_unit_tests5.cpp> int main() { test_main(0, nullptr); } 

然后可以编译和运行例如

 g++ main.cpp -lboost_system -lboost_serialization && ./a.out 

没有输出意味着没有错误。

dynamic_bitset<>不可序列化,因为您已经发现( std::bitset<N>是不同的类型)。

不过不用担心,你可以毫不费力地添加它:

namespace boost { namespace serialization {

    template <typename Ar, typename Block, typename Alloc>
        void save(Ar& ar, dynamic_bitset<Block, Alloc> const& bs, unsigned) {
            size_t num_bits = bs.size();
            std::vector<Block> blocks(bs.num_blocks());
            to_block_range(bs, blocks.begin());

            ar & num_bits & blocks;
        }

    template <typename Ar, typename Block, typename Alloc>
        void load(Ar& ar, dynamic_bitset<Block, Alloc>& bs, unsigned) {
            size_t num_bits;
            std::vector<Block> blocks;
            ar & num_bits & blocks;

            bs.resize(num_bits);
            from_block_range(blocks.begin(), blocks.end(), bs);
            bs.resize(num_bits);
        }

    template <typename Ar, typename Block, typename Alloc>
        void serialize(Ar& ar, dynamic_bitset<Block, Alloc>& bs, unsigned version) {
            split_free(ar, bs, version);
        }

} }

这有效,例如Live On Coliru

int main() {
    A a;
    for (int i=0; i<128; ++i)
        a.x.resize(11*i, i%2);

    std::stringstream ss;
    {
        boost::archive::text_oarchive oa(ss);
        oa << a;
    }
    std::cout << ss.str();
    {
        boost::archive::text_iarchive ia(ss);
        A b;
        ia >> b;

        assert(a.x == b.x);
    }
}

请注意,如果您无法复制块向量,则可以直接在m_bits级别上添加序列化,但这需要进行干扰更改(至少需要访问朋友)。

这样的事情很容易被添加到拉取请求中。

更新添加了拉取请求

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM