2011-02-09 73 views
3

我正在編寫一個將處理存儲和序列化用戶定義類型的庫。用戶定義的類型必須是可序列化的。使用Boost序列化註冊用戶提供的派生類型

但是,該庫使用模板來創建用戶類型的容器。我不知道如何通過模板將容器類型導出到boost :: serialization。我能做到的唯一方法是強制庫的用戶到每個容器類型的BOOST_CLASS_EXPORT_GUID()。

我試着通過查看boost/serialization/export.hpp來解壓宏,但它有點複雜...有沒有辦法導出類作爲模板實例的一部分?或者另一種編寫庫來輕鬆序列化用戶定義類型的容器的方法?

#include <iostream> 
#include <vector> 

#include <boost/foreach.hpp> 
#include <boost/serialization/access.hpp> 
#include <boost/serialization/vector.hpp> 
#include <boost/serialization/base_object.hpp> 
#include <boost/serialization/export.hpp> 

#include <boost/archive/text_oarchive.hpp> 

////////////////////////////////////////////////////////////////////////////// 
// Example code that would reside in the library 
////////////////////////////////////////////////////////////////////////////// 

struct type_container_base { 
private: 
    virtual void make_abstract() const {} 
    friend class ::boost::serialization::access; 
    template <typename ARCHIVE> 
    void serialize(ARCHIVE &, const unsigned int) {}  
}; 

BOOST_SERIALIZATION_ASSUME_ABSTRACT(type_container_base) 

template <typename USER_TYPE> 
struct type_container : type_container_base { 
    void add(const USER_TYPE& d) { _vector.push_back(d); } 
private: 
    std::vector<USER_TYPE> _vector; 
    friend class ::boost::serialization::access; 
    template <typename ARCHIVE> 
    void serialize(ARCHIVE & ar, const unsigned int) { 
     ar & ::boost::serialization::base_object<type_container_base>(*this); 
     ar & _vector; 
    } 
}; 

////////////////////////////////////////////////////////////////////////////// 
// Example user code that would use the library 
////////////////////////////////////////////////////////////////////////////// 

struct user_type { 
    user_type(int i) : _val(i) {} 
private: 
    int _val; 
    friend class ::boost::serialization::access; 
    template <typename ARCHIVE> 
    void serialize(ARCHIVE & ar, const unsigned int) { 
     ar & _val; 
    } 
}; 

// *** Is there a better way than forcing the user to do this for every 
// *** user_type they want to use with the library? 
BOOST_CLASS_EXPORT_GUID(type_container<user_type>, "type_container<user_type>") 

int main() { 
    std::vector<type_container_base*> containers; 
    type_container<user_type>* tc = new type_container<user_type>(); 
    tc->add(user_type(7)); 
    tc->add(user_type(42)); 
    tc->add(user_type(1776)); 
    containers.push_back(tc); 
    { 
     boost::archive::text_oarchive ar(std::cout); 
     const std::size_t size = containers.size(); 
     ar << size; 
     BOOST_FOREACH(type_container_base* p, containers) 
      ar << p; 
    } 
    return 0; 
} 

回答

0

也許類似的規定:

#define BOOST_CLASS_TEMPLATE_EXPORT_IMPLEMENT(T)    \ 
    namespace boost {          \ 
    namespace archive {          \ 
    namespace detail {          \ 
    namespace {            \ 
    template<typename U>          \ 
    struct init_guid< T<U> > {        \ 
     static guid_initializer< T<U> > const & g;   \ 
    };              \ 
    template<typename U>          \ 
    guid_initializer< T<U> > const & init_guid< T<U> >::g = \ 
     ::boost::serialization::singleton<     \ 
      guid_initializer< T<U> >       \ 
     >::get_mutable_instance().export_guid();    \ 
    }}}}              \ 
/**/ 

#define BOOST_CLASS_TEMPLATE_EXPORT_KEY2(T, K) \ 
namespace boost {        \ 
namespace serialization {      \ 
template<typename U>       \ 
struct guid_defined< T<U> > : boost::mpl::true_ {}; \ 
template<typename U>       \ 
inline const char * guid< T<U> >(){   \ 
    return K + "<" + guid<U>() + ">"; //this doesn't work, I know! \ 
}            \ 
} /* serialization */       \ 
} /* boost */         \ 
/**/ 

#define BOOST_CLASS_TEMPLATE_EXPORT_KEY(T)        \ 
    BOOST_CLASS_TEMPLATE_EXPORT_KEY2(T, BOOST_PP_STRINGIZE(T))               \ 
/**/ 

#define BOOST_CLASS_TEMPLATE_EXPORT_GUID(T, K)       \ 
BOOST_CLASS_TEMPLATE_EXPORT_KEY2(T, K)         \ 
BOOST_CLASS_TEMPLATE_EXPORT_IMPLEMENT(T)        \ 
/**/ 

這可能與一些額外的調整,以它的工作。當然,它可能會假設user_type也已經導出。但是,它仍然會減少組合維度,所有您需要的是每個類的一個導出和每個類模板的一個導出,而不是每個模板實例的一個導出(類的數量X類模板的數量)。

這可能是應該向負責Boost.Serialization庫的人員(我猜那將是Robert Ramey)要求/請求/提議的那種東西。

+0

嗯......那裏可能有東西。只是爲了澄清,我的問題是不導出容器類型,這是我不能導出一個類型,它是參數尚不知道的模板的專業化。這是因爲BOOST _...宏在命名空間範圍內運行,所以我需要用戶處理其類型(和/或相關容器類型)的導出。而我希望庫可以通過直接插入序列化庫來處理它。 – vsekhar 2011-02-09 23:08:08

相關問題