How can boost::serialization be used with std::shared_ptr from C++11?

后端 未结 7 1875
礼貌的吻别
礼貌的吻别 2020-12-08 20:23

I know that there is a Boost module for serialization of boost::shared_ptr, but I cannot find anything for std::shared_ptr.

Also, I don\'t know how to implement it e

7条回答
  •  挽巷
    挽巷 (楼主)
    2020-12-08 20:47

    This is the result of rolling your own based on the boost shared pointer header e.g. based on .

    Just copy & paste below into a header file and include it:

    #ifndef BOOST_SERIALIZATION_STD_SHARED_PTR_HPP
    #define BOOST_SERIALIZATION_STD_SHARED_PTR_HPP
    
    // MS compatible compilers support #pragma once
    #if defined(_MSC_VER) && (_MSC_VER >= 1020)
    # pragma once
    #endif
    
    /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
    // shared_ptr.hpp: serialization for boost shared pointer
    
    // (C) Copyright 2004 Robert Ramey and Martin Ecker
    // Use, modification and distribution is subject to the Boost Software
    // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
    // http://www.boost.org/LICENSE_1_0.txt)
    
    //  See http://www.boost.org for updates, documentation, and revision history.
    
    #include  // NULL
    
    #include 
    #include 
    #include 
    
    #include 
    #include 
    
    #include 
    #include 
    #include 
    #include 
    
    /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
    // shared_ptr serialization traits
    // version 1 to distinguish from boost 1.32 version. Note: we can only do this
    // for a template when the compiler supports partial template specialization
    
    #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
        namespace boost {
        namespace serialization{
            template
            struct version< ::std::shared_ptr< T > > {
                typedef mpl::integral_c_tag tag;
                #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206))
                typedef BOOST_DEDUCED_TYPENAME mpl::int_<1> type;
                #else
                typedef mpl::int_<1> type;
                #endif
                #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570))
                BOOST_STATIC_CONSTANT(int, value = 1);
                #else
                BOOST_STATIC_CONSTANT(int, value = type::value);
                #endif
            };
            // don't track shared pointers
            template
            struct tracking_level< ::std::shared_ptr< T > > {
                typedef mpl::integral_c_tag tag;
                #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206))
                typedef BOOST_DEDUCED_TYPENAME mpl::int_< ::boost::serialization::track_never> type;
                #else
                typedef mpl::int_< ::boost::serialization::track_never> type;
                #endif
                #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570))
                BOOST_STATIC_CONSTANT(int, value = ::boost::serialization::track_never);
                #else
                BOOST_STATIC_CONSTANT(int, value = type::value);
                #endif
            };
        }}
        #define BOOST_SERIALIZATION_SHARED_PTR(T)
    #else
        // define macro to let users of these compilers do this
        #define BOOST_SERIALIZATION_SHARED_PTR(T)                         \
        BOOST_CLASS_VERSION(                                              \
            ::std::shared_ptr< T >,                                     \
            1                                                             \
        )                                                                 \
        BOOST_CLASS_TRACKING(                                             \
            ::std::shared_ptr< T >,                                     \
            ::boost::serialization::track_never                           \
        )                                                                 \
        /**/
    #endif
    
    namespace boost {
    namespace serialization{
    
    #ifndef BOOST_SERIALIZATION_SHARED_PTR_HPP
    struct null_deleter {
        void operator()(void const *) const {}
    };
    #endif
    
    /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
    // serialization for shared_ptr
    
    template
    inline void save(
        Archive & ar,
        const std::shared_ptr< T > &t,
        const unsigned int /* file_version */
    ){
        // The most common cause of trapping here would be serializing
        // something like shared_ptr.  This occurs because int
        // is never tracked by default.  Wrap int in a trackable type
        BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never));
        const T * t_ptr = t.get();
        ar << boost::serialization::make_nvp("px", t_ptr);
    }
    
    template
    inline void load(
        Archive & ar,
        std::shared_ptr< T > &t,
        const unsigned int /*file_version*/
    ){
        // The most common cause of trapping here would be serializing
        // something like shared_ptr.  This occurs because int
        // is never tracked by default.  Wrap int in a trackable type
        BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never));
        T* r;
        ar >> boost::serialization::make_nvp("px", r);
        ar.reset(t,r);
    }
    
    template
    inline void serialize(
        Archive & ar,
        std::shared_ptr< T > &t,
        const unsigned int file_version
    ){
        // correct shared_ptr serialization depends upon object tracking
        // being used.
        BOOST_STATIC_ASSERT(
            boost::serialization::tracking_level< T >::value
            != boost::serialization::track_never
        );
        boost::serialization::split_free(ar, t, file_version);
    }
    
    } // namespace serialization
    } // namespace boost
    
    #endif // BOOST_SERIALIZATION_STD_SHARED_PTR_HPP
    

    You can view the differences to here

    Basically,

    • renamed include guard
    • changed boost::shared_ptr to std::shared_ptr
    • included instead of
    • protected null_deleter from redefinition in case you also use boost::shared_ptr
    • deleted BOOST_SERIALIZATION_SHARED_PTR_132_HPP - whatever that is about?

    So far, this seems to be working just fine.

提交回复
热议问题