5

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;
}

コンパイルするとエラーが発生する (boost 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’
4

2 に答える 2

5

Boost Dynamic Bitset にシリアル化サポートを追加するプル リクエストを提出しました。

パブリック インターフェイスを使用したシリアル化は、 (およびその後の)のコピーが必要なためto_block_range()、最適ではありません。from_block_range()m_bitsresize()

Boost Dynamic Bitset に一般的な実装を追加しました。変更は、develop または master (1_58_0) に対して完全にマージされます。

変更点

で追加された実装

  • 最小限の侵入性、ネストされたフレンド ( class serialization_impl;) のみが「鍵穴」に前方宣言され、必要なフレンド アクセス
  • このクラスは、Boost Serialization の実際の ADL フックと同様に、別のヘッダーに実装されます (dynamic_bitset/serialization.hppシリアライゼーションをサポートする他の Boost ライブラリと同様)。
  • boost/dynamic_bitset/serialization.hppこれは、実際に含まれていない限り、Boost Serialization への依存関係が存在しないことを意味します。
  • ゼロ コピーが実現されます ( std::vector<Block>Boost Serialization の組み込みサポートを活用)

テスト

プル リクエストの 2 番目のコミットは、この機能のテストを追加します。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

出力がないということは、エラーがないことを意味します。

于 2015-06-24T00:21:38.613 に答える
4

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レベルに直接追加するのも同様に簡単ですが、それには煩わしい変更が必要です (少なくともフレンド アクセスが必要です)。

このようなものは、プル リクエストのブーストに簡単に追加できます。

そのプルリクエストを追加したアップデート

于 2015-06-23T22:25:57.720 に答える