2010-09-14 50 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; 
}