myoukakuのブログ

C++でゲームエンジンを作っていきます。

Boost.Serialization で std::queue をシリアライズしようとするとエラーになった

現象

Boost.Serializationでstd::queueをシリアライズ/デシリアライズしようとするとビルドエラーになる場合があります。 具体的には以下のコードがエラーになります。

#include <boost/serialization/queue.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <sstream>

int main(void)
{
    std::stringstream ss;
    std::queue<int> q;
    boost::archive::text_oarchive oa(ss);
    oa << boost::serialization::make_nvp("q", q);  // (1)
    
    return 0;
}

(1)の行でエラーになります。 エラーメッセージは

error C2780: 'void boost::archive::save(Archive &,T &)' : 2 引数が必要です - 3 が設定されます。

他のアーカイブ(xml_oarchive,binary_oarchive)でも同様です。

また、text_iarchive(xml_iarchive,binary_iarchive)でデシリアライズしようとするとload関数で同様のエラーが出ます。

原因

queue.hppに定義されているserialize関数からは3つの引数を取るsave,load関数が呼び出されていますが、それが定義されていないのが原因のようです。

対処法

Boost.Serializationのqueueのテストを見てみると、queue.hpp だけでなく deque.hpp もインクルードしていました。 試しにdeque.hppもインクルードしてみたところビルドエラーは出なくなりました。 deque.hppの中を見てみると3引数版のsave,load関数が定義されており、これでビルドが通るようになったのだと思います。

結論

queueをシリアライズするときは<boost/serialization/deque.hpp>もインクルードする。 これが仕様なのかバグなのかはよくわかりませんでした。