代码之家  ›  专栏  ›  技术社区  ›  Edward Strange

boost.序列化-免费版本和基类实现

  •  1
  • Edward Strange  · 技术社区  · 15 年前

    #include <boost/serialization/serialization.hpp>
    template < typename T >
    struct test_base
    {
      // works...
      //template < typename Archive >
      //void serialize(Archive &, unsigned int const)
     // {
      //}
    };
    
    template < typename T >
    void f(test_base<T> const&) {}
    
    struct test_derived : test_base<int>
    {
    };
    
    namespace boost { namespace serialization {
    
    template < typename Archive, typename T >
    void serialize(Archive &, test_base<T> &, unsigned int const)
    {
    }
    
    }}
    
    #include <boost/archive/binary_oarchive.hpp>
    #include <sstream>
    int main()
    {
      int x = 5;
      test_derived d;
      //boost::serialization::serialize(x, d, 54); // <- works.
    
      std::ostringstream str;
      boost::archive::binary_oarchive out(str);
      out & d; // no worky.
    }
    

    如果可能的话,我想免费的版本可以用。它是?

    上面的版本抛出了关于serialize不是test\u派生的成员的错误。

    1 回复  |  直到 15 年前
        1
  •  0
  •   Daniel    15 年前

    澄清问题发生的原因:
    序列化必须找到实现序列化函数的方法。作为类方法或(在您的示例中)在boost::serialization命名空间中定义函数的非侵入式方法。
    因此,编译器必须以某种方式决定选择哪个实现。因此,boost有一个boost::serialization::serialize模板函数的“默认”实现。

    template<class Archive, class T>
    inline void serialize(Archive & ar, T & t, const BOOST_PFTO unsigned int file_version)
    


    在该函数中有一个对T::serialize(…)的调用。因此,当您不需要直观版本时,必须使用比默认函数模板更显式的内容重写boost::serialization::serialize函数。
    现在问题是:


    b) 使用泛型函数而不强制转换(T是test_派生的&)


    解决方案:

    如果这对您来说不是一个可行的解决方案,您还可以更明确地告诉编译器要调用什么:

    out & *((test_base<int>*)&d);
    


    并将其包装在某个助手函数中(因为没有人愿意整天查看此类代码)

    我希望这是一个清晰的描述和帮助

    如果我的解释不清楚,下面是一个例子:

    #include <iostream>
    class Base
    {
    public:
        virtual ~Base()
        {
        }
    };
    
    class Derived : public Base
    {
    public:
        virtual ~Derived()
        {
        }
    };
    
    
    void foo(Base& bar)
    {
        std::cout << "special" << std::endl;
    }
    
    template<typename T>
    void foo(T& bar)
    {
        std::cout << "generic" << std::endl;
    }
    
    int main()
    {
        Derived derived;
        foo(derived);         // => call to generic implementation
        foo(*((Base*) &bla)); // => call to special 
        return 0;
    }