Anupama Pathirage
Anupama Pathirage

Reputation: 691

Boost serialization with template classes

I'm adding boost serialization support for existing C++ project in linux. In that project there is Template class Called ContainerT and MString is derived from that class by using template type as char.

The MString type is used in Person Class and I want to serialize data in Person Class.The Person class is like below.(Since the actual project is large only part of it is given here)

#ifndef PERSON_H_
#define PERSON_H_

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <string>
#include <map>
#include "Container.h"
class Person
{
public:
    Person();
    Person(std::string _zName,int _iAge);
    ~Person();

private:    
    std::string z_Name;
    int i_Age;
    MString z_CountryCode;


    //Serailization
    //Allow serialization to access non-public data members.
    friend class boost::serialization::access;

    template <typename Archive> 
    void serialize(Archive &ar, const unsigned int version) 
    { 
        ar & z_Name; 
        ar & i_Age; 
        ar & z_CountryCode; 
    }   
};


#endif /* PERSON_H_ */

The Template Class is as follows.

#ifndef CONTAINER_H_
#define CONTAINER_H_


#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>

template<typename T>
class ContainerT;

template<typename T>
class ContainerDataT
{
public:
    ContainerDataT();
    ~ContainerDataT(){};

    T*  GetData(){return p_Data;};

private:
    friend class ContainerT<T>;

    T           p_Data[];

    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive &ar, const unsigned int file_version)
    {
        ar & p_Data;
    }
};

template<typename T>
class ContainerT
{
public:

    ContainerT();           
    ContainerT(const T* _zData);
    ~ContainerT();
    const T* GetMString() const;

private:

    ContainerDataT<T>*  p_Data;


    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive &ar, const unsigned int file_version)
    {
        ar & p_Data;
    }
};

template<typename T>
ContainerT<T>::ContainerT()
{
    p_Data = (ContainerDataT<T>*)malloc(1);
    p_Data->GetData()[0] = 0;
}


template<typename T>
ContainerT<T>::ContainerT(const T* _zData)
{
    const T* pChar = _zData;

    while(*pChar != 0)
        ++pChar;
    int iLength = pChar - _zData;

    p_Data = (ContainerDataT<T>*)malloc(500);
    memcpy(p_Data->GetData(), _zData, iLength * sizeof(T));
    p_Data->GetData()[iLength] = 0;
}

template<typename T>
ContainerT<T>::~ContainerT()
{
    free(p_Data);
}

template<typename T>
const T* ContainerT<T>::GetMString() const
{
    return p_Data->GetData();
}


typedef ContainerT<char>    MString;

#endif /* CONTAINER_H_ */

When I Compling the code I get the following errors when I try to serialize MString. If I commented the ar & z_CountryCode; line in Person class every thing is working fine. Can someone help me on identifying the issue with that. Is there any special way to serialize the template classes.?

/usr/include/boost/type_traits/is_abstract.hpp: In instantiation of ‘boost::detail::is_abstract_imp2<ContainerDataT<char> >’:
/usr/include/boost/type_traits/is_abstract.hpp:121:   instantiated from ‘const bool boost::detail::is_abstract_imp<ContainerDataT<char> >::value’
/usr/include/boost/type_traits/is_abstract.hpp:128:   instantiated from ‘boost::is_abstract<ContainerDataT<char> >’
/usr/include/boost/serialization/is_abstract.hpp:32:   instantiated from ‘boost::serialization::is_abstract<ContainerDataT<char> >’
/usr/include/boost/mpl/if.hpp:67:   instantiated from ‘boost::mpl::if_<boost::serialization::is_abstract<ContainerDataT<char> >, boost::mpl::identity<boost::archive::detail::save_pointer_type<boost::archive::text_oarchive, ContainerDataT<char>*>::abstract<ContainerDataT<char> > >, boost::mpl::identity<boost::archive::detail::save_pointer_type<boost::archive::text_oarchive, ContainerDataT<char>*>::non_abstract<ContainerDataT<char> > > >’
/usr/include/boost/mpl/eval_if.hpp:37:   instantiated from ‘boost::mpl::eval_if<boost::serialization::is_abstract<ContainerDataT<char> >, boost::mpl::identity<boost::archive::detail::save_pointer_type<boost::archive::text_oarchive, ContainerDataT<char>*>::abstract<ContainerDataT<char> > >, boost::mpl::identity<boost::archive::detail::save_pointer_type<boost::archive::text_oarchive, ContainerDataT<char>*>::non_abstract<ContainerDataT<char> > > >’
/usr/include/boost/archive/detail/oserializer.hpp:359:   instantiated from ‘static const boost::archive::detail::basic_pointer_oserializer* boost::archive::detail::save_pointer_type<Archive, TPtr>::register_type(Archive&, T&) [with T = ContainerDataT<char>, Archive = boost::archive::text_oarchive, TPtr = ContainerDataT<char>*]’
/usr/include/boost/archive/detail/oserializer.hpp:460:   instantiated from ‘static void boost::archive::detail::save_pointer_type<Archive, TPtr>::invoke(Archive&, TPtr) [with Archive = boost::archive::text_oarchive, TPtr = ContainerDataT<char>*]’
/usr/include/boost/archive/detail/oserializer.hpp:536:   instantiated from ‘void boost::archive::save(Archive&, const T&) [with Archive = boost::archive::text_oarchive, T = ContainerDataT<char>*]’
/usr/include/boost/archive/basic_text_oarchive.hpp:78:   instantiated from ‘void boost::archive::basic_text_oarchive<Archive>::save_override(T&, int) [with T = ContainerDataT<char>* const, Archive = boost::archive::text_oarchive]’
/usr/include/boost/archive/detail/interface_oarchive.hpp:78:   instantiated from ‘Archive& boost::archive::detail::interface_oarchive<Archive>::operator<<(T&) [with T = ContainerDataT<char>* const, Archive = boost::archive::text_oarchive]’
/usr/include/boost/archive/detail/interface_oarchive.hpp:86:   instantiated from ‘Archive& boost::archive::detail::interface_oarchive<Archive>::operator&(T&) [with T = ContainerDataT<char>*, Archive = boost::archive::text_oarchive]’
Container.h:52:   instantiated from ‘void ContainerT<T>::serialize(Archive&, unsigned int) [with Archive = boost::archive::text_oarchive, T = char]’
/usr/include/boost/serialization/access.hpp:109:   instantiated from ‘static void boost::serialization::access::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = ContainerT<char>]’
/usr/include/boost/serialization/serialization.hpp:81:   instantiated from ‘void boost::serialization::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = ContainerT<char>]’
/usr/include/boost/serialization/serialization.hpp:140:   instantiated from ‘void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = ContainerT<char>]’
/usr/include/boost/archive/detail/oserializer.hpp:148:   instantiated from ‘void boost::archive::detail::oserializer<Archive, T>::save_object_data(boost::archive::detail::basic_oarchive&, const void*) const [with Archive = boost::archive::text_oarchive, T = ContainerT<char>]’
Main.cpp:110:   instantiated from here
/usr/include/boost/type_traits/is_abstract.hpp:81: error: invalid application of ‘sizeof’ to incomplete type ‘boost::STATIC_ASSERTION_FAILURE<false>’
/usr/include/boost/archive/detail/oserializer.hpp: In static member function ‘static void boost::archive::detail::save_non_pointer_type<Archive, T>::invoke(Archive&, const T&) [with Archive = boost::archive::text_oarchive, T = char [0u]]’:
/usr/include/boost/archive/detail/oserializer.hpp:536:   instantiated from ‘void boost::archive::save(Archive&, const T&) [with Archive = boost::archive::text_oarchive, T = char [0u]]’
/usr/include/boost/archive/basic_text_oarchive.hpp:78:   instantiated from ‘void boost::archive::basic_text_oarchive<Archive>::save_override(T&, int) [with T = const char [0u], Archive = boost::archive::text_oarchive]’
/usr/include/boost/archive/detail/interface_oarchive.hpp:78:   instantiated from ‘Archive& boost::archive::detail::interface_oarchive<Archive>::operator<<(T&) [with T = const char [0u], Archive = boost::archive::text_oarchive]’
/usr/include/boost/archive/detail/interface_oarchive.hpp:86:   instantiated from ‘Archive& boost::archive::detail::interface_oarchive<Archive>::operator&(T&) [with T = char [0u], Archive = boost::archive::text_oarchive]’
Container.h:29:   instantiated from ‘void ContainerDataT<T>::serialize(Archive&, unsigned int) [with Archive = boost::archive::text_oarchive, T = char]’
/usr/include/boost/serialization/access.hpp:109:   instantiated from ‘static void boost::serialization::access::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = ContainerDataT<char>]’
/usr/include/boost/serialization/serialization.hpp:81:   instantiated from ‘void boost::serialization::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = ContainerDataT<char>]’
/usr/include/boost/serialization/serialization.hpp:140:   instantiated from ‘void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = ContainerDataT<char>]’
/usr/include/boost/archive/detail/oserializer.hpp:226:   instantiated from ‘boost::archive::detail::pointer_oserializer<T, Archive>::pointer_oserializer() [with T = ContainerDataT<char>, Archive = boost::archive::text_oarchive]’
/usr/include/boost/archive/detail/oserializer.hpp:198:   instantiated from ‘const boost::archive::detail::pointer_oserializer<ContainerDataT<char>, boost::archive::text_oarchive> boost::archive::detail::pointer_oserializer<ContainerDataT<char>, boost::archive::text_oarchive>::instance’
/usr/include/boost/archive/detail/oserializer.hpp:190:   instantiated from ‘static const boost::archive::detail::pointer_oserializer<T, Archive>& boost::archive::detail::pointer_oserializer<T, Archive>::instantiate() [with T = ContainerDataT<char>, Archive = boost::archive::text_oarchive]’
/usr/include/boost/archive/detail/oserializer.hpp:515:   instantiated from ‘const boost::archive::detail::basic_pointer_oserializer& boost::archive::detail::instantiate_pointer_oserializer(Archive*, T*) [with Archive = boost::archive::text_oarchive, T = ContainerDataT<char>]’
/usr/include/boost/archive/detail/interface_oarchive.hpp:58:   instantiated from ‘const boost::archive::detail::basic_pointer_oserializer* boost::archive::detail::interface_oarchive<Archive>::register_type(const T*) [with T = ContainerDataT<char>, Archive = boost::archive::text_oarchive]’
/usr/include/boost/archive/detail/oserializer.hpp:344:   instantiated from ‘static const boost::archive::detail::basic_pointer_oserializer* boost::archive::detail::save_pointer_type<Archive, TPtr>::non_abstract<T>::register_type(Archive&) [with T = ContainerDataT<char>, Archive = boost::archive::text_oarchive, TPtr = ContainerDataT<char>*]’
/usr/include/boost/archive/detail/oserializer.hpp:360:   instantiated from ‘static const boost::archive::detail::basic_pointer_oserializer* boost::archive::detail::save_pointer_type<Archive, TPtr>::register_type(Archive&, T&) [with T = ContainerDataT<char>, Archive = boost::archive::text_oarchive, TPtr = ContainerDataT<char>*]’
/usr/include/boost/archive/detail/oserializer.hpp:460:   instantiated from ‘static void boost::archive::detail::save_pointer_type<Archive, TPtr>::invoke(Archive&, TPtr) [with Archive = boost::archive::text_oarchive, TPtr = ContainerDataT<char>*]’
/usr/include/boost/archive/detail/oserializer.hpp:536:   instantiated from ‘void boost::archive::save(Archive&, const T&) [with Archive = boost::archive::text_oarchive, T = ContainerDataT<char>*]’
/usr/include/boost/archive/basic_text_oarchive.hpp:78:   instantiated from ‘void boost::archive::basic_text_oarchive<Archive>::save_override(T&, int) [with T = ContainerDataT<char>* const, Archive = boost::archive::text_oarchive]’
/usr/include/boost/archive/detail/interface_oarchive.hpp:78:   instantiated from ‘Archive& boost::archive::detail::interface_oarchive<Archive>::operator<<(T&) [with T = ContainerDataT<char>* const, Archive = boost::archive::text_oarchive]’
/usr/include/boost/archive/detail/interface_oarchive.hpp:86:   instantiated from ‘Archive& boost::archive::detail::interface_oarchive<Archive>::operator&(T&) [with T = ContainerDataT<char>*, Archive = boost::archive::text_oarchive]’
Container.h:52:   instantiated from ‘void ContainerT<T>::serialize(Archive&, unsigned int) [with Archive = boost::archive::text_oarchive, T = char]’
/usr/include/boost/serialization/access.hpp:109:   instantiated from ‘static void boost::serialization::access::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = ContainerT<char>]’
/usr/include/boost/serialization/serialization.hpp:81:   instantiated from ‘void boost::serialization::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = ContainerT<char>]’
/usr/include/boost/serialization/serialization.hpp:140:   instantiated from ‘void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = ContainerT<char>]’
/usr/include/boost/archive/detail/oserializer.hpp:148:   instantiated from ‘void boost::archive::detail::oserializer<Archive, T>::save_object_data(boost::archive::detail::basic_oarchive&, const void*) const [with Archive = boost::archive::text_oarchive, T = ContainerT<char>]’
Main.cpp:110:   instantiated from here
/usr/include/boost/archive/detail/oserializer.hpp:316: error: invalid application of ‘sizeof’ to incomplete type ‘boost::STATIC_ASSERTION_FAILURE<false>’
/usr/include/boost/archive/detail/iserializer.hpp: In static member function ‘static void boost::archive::detail::load_non_pointer_type<Archive, T>::invoke(Archive&, T&) [with Archive = boost::archive::text_iarchive, T = char [0u]]’:
/usr/include/boost/archive/detail/iserializer.hpp:572:   instantiated from ‘void boost::archive::load(Archive&, T&) [with Archive = boost::archive::text_iarchive, T = char [0u]]’
/usr/include/boost/archive/basic_text_iarchive.hpp:64:   instantiated from ‘void boost::archive::basic_text_iarchive<Archive>::load_override(T&, int) [with T = char [0u], Archive = boost::archive::text_iarchive]’
/usr/include/boost/archive/text_iarchive.hpp:64:   instantiated from ‘void boost::archive::text_iarchive_impl<Archive>::load_override(T&, int) [with T = char [0u], Archive = boost::archive::text_iarchive]’
/usr/include/boost/archive/detail/interface_iarchive.hpp:76:   instantiated from ‘Archive& boost::archive::detail::interface_iarchive<Archive>::operator>>(T&) [with T = char [0u], Archive = boost::archive::text_iarchive]’
/usr/include/boost/archive/detail/interface_iarchive.hpp:83:   instantiated from ‘Archive& boost::archive::detail::interface_iarchive<Archive>::operator&(T&) [with T = char [0u], Archive = boost::archive::text_iarchive]’
Container.h:29:   instantiated from ‘void ContainerDataT<T>::serialize(Archive&, unsigned int) [with Archive = boost::archive::text_iarchive, T = char]’
/usr/include/boost/serialization/access.hpp:109:   instantiated from ‘static void boost::serialization::access::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_iarchive, T = ContainerDataT<char>]’
/usr/include/boost/serialization/serialization.hpp:81:   instantiated from ‘void boost::serialization::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_iarchive, T = ContainerDataT<char>]’
/usr/include/boost/serialization/serialization.hpp:140:   instantiated from ‘void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::archive::text_iarchive, T = ContainerDataT<char>]’
/usr/include/boost/archive/detail/iserializer.hpp:332:   instantiated from ‘boost::archive::detail::pointer_iserializer<T, Archive>::pointer_iserializer() [with T = ContainerDataT<char>, Archive = boost::archive::text_iarchive]’
/usr/include/boost/archive/detail/iserializer.hpp:211:   instantiated from ‘const boost::archive::detail::pointer_iserializer<ContainerDataT<char>, boost::archive::text_iarchive> boost::archive::detail::pointer_iserializer<ContainerDataT<char>, boost::archive::text_iarchive>::instance’
/usr/include/boost/archive/detail/iserializer.hpp:203:   instantiated from ‘static const boost::archive::detail::pointer_iserializer<T, Archive>& boost::archive::detail::pointer_iserializer<T, Archive>::instantiate() [with T = ContainerDataT<char>, Archive = boost::archive::text_iarchive]’
/usr/include/boost/archive/detail/iserializer.hpp:546:   instantiated from ‘const boost::archive::detail::basic_pointer_iserializer& boost::archive::detail::instantiate_pointer_iserializer(Archive*, T*) [with Archive = boost::archive::text_iarchive, T = ContainerDataT<char>]’
/usr/include/boost/archive/detail/interface_iarchive.hpp:57:   instantiated from ‘const boost::archive::detail::basic_pointer_iserializer* boost::archive::detail::interface_iarchive<Archive>::register_type(T*) [with T = ContainerDataT<char>, Archive = boost::archive::text_iarchive]’
/usr/include/boost/archive/detail/iserializer.hpp:449:   instantiated from ‘static const boost::archive::detail::basic_pointer_iserializer* boost::archive::detail::load_pointer_type<Archive, Tptr>::non_abstract<T>::register_type(Archive&) [with T = ContainerDataT<char>, Archive = boost::archive::text_iarchive, Tptr = ContainerDataT<char>*]’
/usr/include/boost/archive/detail/iserializer.hpp:465:   instantiated from ‘static const boost::archive::detail::basic_pointer_iserializer* boost::archive::detail::load_pointer_type<Archive, Tptr>::register_type(Archive&, T&) [with T = ContainerDataT<char>, Archive = boost::archive::text_iarchive, Tptr = ContainerDataT<char>*]’
/usr/include/boost/archive/detail/iserializer.hpp:485:   instantiated from ‘static void boost::archive::detail::load_pointer_type<Archive, Tptr>::invoke(Archive&, Tptr&) [with Archive = boost::archive::text_iarchive, Tptr = ContainerDataT<char>*]’
/usr/include/boost/archive/detail/iserializer.hpp:572:   instantiated from ‘void boost::archive::load(Archive&, T&) [with Archive = boost::archive::text_iarchive, T = ContainerDataT<char>*]’
/usr/include/boost/archive/basic_text_iarchive.hpp:64:   instantiated from ‘void boost::archive::basic_text_iarchive<Archive>::load_override(T&, int) [with T = ContainerDataT<char>*, Archive = boost::archive::text_iarchive]’
/usr/include/boost/archive/text_iarchive.hpp:64:   instantiated from ‘void boost::archive::text_iarchive_impl<Archive>::load_override(T&, int) [with T = ContainerDataT<char>*, Archive = boost::archive::text_iarchive]’
/usr/include/boost/archive/detail/interface_iarchive.hpp:76:   instantiated from ‘Archive& boost::archive::detail::interface_iarchive<Archive>::operator>>(T&) [with T = ContainerDataT<char>*, Archive = boost::archive::text_iarchive]’
/usr/include/boost/archive/detail/interface_iarchive.hpp:83:   instantiated from ‘Archive& boost::archive::detail::interface_iarchive<Archive>::operator&(T&) [with T = ContainerDataT<char>*, Archive = boost::archive::text_iarchive]’
Container.h:52:   instantiated from ‘void ContainerT<T>::serialize(Archive&, unsigned int) [with Archive = boost::archive::text_iarchive, T = char]’
/usr/include/boost/serialization/access.hpp:109:   instantiated from ‘static void boost::serialization::access::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_iarchive, T = ContainerT<char>]’
/usr/include/boost/serialization/serialization.hpp:81:   instantiated from ‘void boost::serialization::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_iarchive, T = ContainerT<char>]’
/usr/include/boost/serialization/serialization.hpp:140:   instantiated from ‘void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::archive::text_iarchive, T = ContainerT<char>]’
/usr/include/boost/archive/detail/iserializer.hpp:160:   instantiated from ‘void boost::archive::detail::iserializer<Archive, T>::load_object_data(boost::archive::detail::basic_iarchive&, void*, unsigned int) const [with Archive = boost::archive::text_iarchive, T = ContainerT<char>]’
Main.cpp:110:   instantiated from here
/usr/include/boost/archive/detail/iserializer.hpp:419: error: invalid application of ‘sizeof’ to incomplete type ‘boost::STATIC_ASSERTION_FAILURE<false>’
/usr/include/boost/serialization/access.hpp: In static member function ‘static void boost::serialization::access::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_iarchive, T = char [0u]]’:
/usr/include/boost/serialization/serialization.hpp:81:   instantiated from ‘void boost::serialization::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_iarchive, T = char [0u]]’
/usr/include/boost/serialization/serialization.hpp:140:   instantiated from ‘void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::archive::text_iarchive, T = char [0u]]’
/usr/include/boost/archive/detail/iserializer.hpp:160:   instantiated from ‘void boost::archive::detail::iserializer<Archive, T>::load_object_data(boost::archive::detail::basic_iarchive&, void*, unsigned int) const [with Archive = boost::archive::text_iarchive, T = char [0u]]’
Main.cpp:112:   instantiated from here
/usr/include/boost/serialization/access.hpp:109: error: request for member ‘serialize’ in ‘t’, which is of non-class type ‘char [0u]’
/usr/include/boost/serialization/access.hpp: In static member function ‘static void boost::serialization::access::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = char [0u]]’:
/usr/include/boost/serialization/serialization.hpp:81:   instantiated from ‘void boost::serialization::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = char [0u]]’
/usr/include/boost/serialization/serialization.hpp:140:   instantiated from ‘void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive, T = char [0u]]’
/usr/include/boost/archive/detail/oserializer.hpp:148:   instantiated from ‘void boost::archive::detail::oserializer<Archive, T>::save_object_data(boost::archive::detail::basic_oarchive&, const void*) const [with Archive = boost::archive::text_oarchive, T = char [0u]]’
Main.cpp:112:   instantiated from here
/usr/include/boost/serialization/access.hpp:109: error: request for member ‘serialize’ in ‘t’, which is of non-class type ‘char [0u]’

Upvotes: 2

Views: 3011

Answers (1)

sehe
sehe

Reputation: 392833

There's more than just a few issues at play here.

Firstly,

  • ContainerDataT<> fails to honour Rule Of Three
  • ContainerT<> fails to honour Rule Of Three
  • There is for malloc/free in C++. Just use the safer new/delete (or better yet, a smart pointer to manage the ownership semantics and lifetimes in an exception safe way).
  • T[] as a member is equivalent to T*.

I'd suggest using standard types to govern the ownership semantics (unique_ptr), or better yet, just use standard library for variable-size dynamically allocated arrays (hint: it's std::vector). If you insist on using dynamically allocated array members, be honest about it to your Serialization function: Live On Coliru

template<typename T>
class ContainerDataT : boost::noncopyable {
public:
    ContainerDataT() : p_Data(new T[10]) { }
    ~ContainerDataT() { delete[] p_Data; }

    T*  GetData(){return p_Data;};

private:
    friend class ContainerT<T>;

    T* p_Data;

    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive &ar, const unsigned int file_version) {
        ar & boost::serialization::make_array(p_Data, 10);
    }
};

So, you can use boost::serialization::make_array to tell Boost Serialization about your intentions.

Here's a simple demo program that demonstrates things (using a fixed size allocated T* p_Data). Note that I simply made p_Data a member object inside ContainerT<> because it seems there is no gain in having double dynamic instantiation.

#ifndef CONTAINER_H_
#define CONTAINER_H_

#include <boost/noncopyable.hpp>
#include <boost/serialization/access.hpp>
#include <boost/serialization/array.hpp>

template<typename T>
class ContainerT;

    template<typename T>
    class ContainerDataT : boost::noncopyable {
    public:
        ContainerDataT() : p_Data(new T[10]) { 
            std::copy_n("0123456789", 10, p_Data);
        }
        ~ContainerDataT() { delete[] p_Data; }

        T*  GetData(){return p_Data;};

    private:
        friend class ContainerT<T>;

        T* p_Data;

        friend class boost::serialization::access;
        template<class Archive>
        void serialize(Archive &ar, const unsigned int file_version) {
            ar & boost::serialization::make_array(p_Data, 10);
        }
    };

template<typename T>
class ContainerT {
public:
    const T* GetMString() const { return p_Data.GetData(); }

private:
    ContainerDataT<T> p_Data;

    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive &ar, const unsigned int file_version) {
        ar & p_Data;
    }
};

typedef ContainerT<char> MString;

#endif /* CONTAINER_H_ */

#ifndef PERSON_H_
#define PERSON_H_

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/string.hpp>
#include <string>

//#include "Container.h"
class Person
{
public:
     Person() = default;
    ~Person() = default;

private:    
    std::string z_Name;
    int         i_Age;
    MString     z_CountryCode;

    //Serailization
    //Allow serialization to access non-public data members.
    friend class boost::serialization::access;

    template <typename Archive> 
    void serialize(Archive &ar, const unsigned int version) 
    { 
        ar & z_Name; 
        ar & i_Age; 
        ar & z_CountryCode; 
    }   
};

#endif /* PERSON_H_ */

int main()
{
    boost::archive::text_oarchive oa(std::cout);

    Person p;
    oa << p;
}

Upvotes: 4

Related Questions