2010-09-14 82 views
1

我有一个“生成器”类,基本上构造了它的子类。为了使用这个东西,我简单地将它分类并传递正确的参数来构建我想要构建的对象。我想序列化这些东西,因为所有的数据都在基础中,所以没有很好的理由针对每个子类。以下是我已经有了为例:boost.serialization - 免费版本和基类实现

#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_derived的成员。

回答

0

说明问题发生的原因:
boost :: serialization必须实现序列化函数的方法。作为类方法或(在你的情况下)在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的电话::连载(...)。所以当你不想使用intusive版本时,你必须用比默认函数模板更明确的东西来覆盖boost :: serialization :: serialize函数。
现在的问题:
在你的情况,编译器,以决定是否
一)选择其中一个参数已被铸造隐含的版本(test_derived &到test_base &)
B)使用通用的功能而无需进行转换( T被test_derived &)
你想编译器使用变体),但编译器更喜欢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; 
}