You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

模板类派生类序列化:加载时基类版本异常问题排查

Boost Serialization: Base Class Uses Derived Class Version During Loading

Problem Description

I'm trying to serialize a class derived from a templated base class (with fixed template parameters). I want the base class serialization to be independent of the derived class (so I can change template parameters later), and the derived class serialization should include both base class data and additional data. Here's my minimal example code:

#include <iostream>
#include <sstream>
#include <boost/serialization/split_member.hpp>
#include <boost/serialization/traits.hpp>
#include <boost/serialization/level.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
using namespace boost::archive;
static constexpr unsigned int base_version = 1;
template<typename T>
struct Base : public boost::serialization::traits<Base<T>, boost::serialization::object_class_info, boost::serialization::track_never, base_version>
{
    T t;
    template<typename A>
    void load(A& a, unsigned int const in_version)
    {
        std::cerr << "Loading Base with version " << in_version << std::endl;
        a & t;
    }
    template<typename A>
    void save(A& a, unsigned int const) const
    {
        std::cerr << "Saving Base with version " << base_version << std::endl;
        a & t;
    }
    BOOST_SERIALIZATION_SPLIT_MEMBER()
};
struct Derived : public Base<int>
{
    int j;
    static constexpr unsigned int version = 2;
    template<typename A>
    void load(A& a, unsigned int const in_version)
    {
        std::cerr << "Loading Derived with version " << in_version << std::endl;
        a & boost::serialization::base_object<Base>(*this);
        a & j;
    }
    template<typename A>
    void save(A& a, unsigned int const) const
    {
        std::cerr << "Saving Derived with version " << version << std::endl;
        a & boost::serialization::base_object<Base>(*this);
        a & j;
    }
    BOOST_SERIALIZATION_SPLIT_MEMBER()
};
BOOST_CLASS_VERSION(Derived,Derived::version)
int main()
{
    Derived d;
    d.t = 1;
    std::stringstream s;
    text_oarchive oa {s};
    oa << d;
    Derived e;
    text_iarchive ia{s};
    ia >> e;
    std::cerr << e.t << std::endl;
    return 0;
}

Output

Saving Derived with version 2
Saving Base with version 1
Loading Derived with version 2
Loading Base with version 2
1

As you can see, the version is correct during saving, but the base class always uses the derived class's version during loading. What's wrong with this code?


Answer

Let's break down the issue here:

The core problem is that in your Derived class's serialization functions, you're using boost::serialization::base_object<Base>(*this) instead of specifying the fully-specialized base class type Base<int>.

When you write base_object<Base>, you're referring to the template class Base<T> rather than the concrete Base<int> specialization that Derived actually inherits from. Boost Serialization relies on knowing the exact type of the base class to look up its associated version information and serialization logic. Since it can't resolve the correct specialization here, it incorrectly passes the derived class's version number (2) to the base class's load function.

Fix the Code

Update the base_object calls in both Derived's load and save functions to explicitly use Base<int>:

// In Derived::load
a & boost::serialization::base_object<Base<int>>(*this);

// In Derived::save
a & boost::serialization::base_object<Base<int>>(*this);

Updated Output

After making this change, your program will output the expected behavior:

Saving Derived with version 2
Saving Base with version 1
Loading Derived with version 2
Loading Base with version 1
1

Key Takeaway

When serializing classes derived from templated base classes, always reference the fully-specialized base type in base_object. This ensures Boost Serialization correctly associates the base class's own version information and serialization functions, keeping the base class's serialization logic independent of the derived class as you intended.


内容的提问来源于stack exchange,提问作者sam.11100

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:50:15