我有一个“生成器”类,它基本上构造了它的子类。要使用这个东西,我只是将它子类化并传递正确的参数来构建我想要构建的对象。我想序列化这些东西,没有充分的理由为每个子类做这个,因为所有数据都在基础中。以下是我的例子:
#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.
}
如果可能,我想要免费版本。是吗?
上面的版本错误地认为序列化不是test_derived的成员。
答案 0 :(得分:0)
澄清问题发生的原因:
boost :: serialization必须实现serialize函数。作为类方法或(在您的情况下)在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(...)的调用。因此,当您不想使用intusive版本时,您必须使用比默认函数模板更明确的内容来覆盖boost :: serialization :: serialize函数。
现在的问题是:
在你的情况下,编译器必须决定是否
a)选择隐含参数的版本(test_derived&amp; to test_base&amp;)
b)使用通用功能而不进行铸造(T是test_derived&amp;)
您希望编译器使用变量a)但编译器更喜欢b)
解决方案:
我不知道一个非常好的解决方案。我想我会使用一个宏来生成带有显式类型的serialize(...)的实现。
如果这对您来说不是一个可能的解决方案,您还可以告诉编译器更明确地调用什么:
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;
}