views:

708

answers:

1

Okay so basically :

i have this simple example:

main.cpp

using namespace VHGO::Resource;

std::list<BaseTable*> tableList;

BigTable* bt1 = new BigTable();
HRESULT hr = S_OK;
hr = bt1->Add(L"TEXTURE", L"..\\Data\\ground.png");
tableList.push_back(bt1);

std::wofstream ofs3(L"VHGOSatData.bif");
boost::archive::xml_woarchive outArch3(ofs3);
outArch3 & BOOST_SERIALIZATION_NVP(tableList);

And my serialization classes

namespace VHGO
{
 typedef std::wstring String;
 typedef std::map<VHGO::String, VHGO::String> PropertyMap;
    namespace Resource
    {
        class BaseTable
        {
            friend class boost::serialization::access;
            friend std::wostream& operator<<(std::wostream& os, const BaseTable& b );
        private:
            template<class Archive>
            void save(Archive& ar, const unsigned int version) const {}

            template<class Archive>
            void load(Archive& ar, const unsigned int version) {}
        public:
            BaseTable()
            {
            }
            //for boost
            virtual ~BaseTable()
            {
            }

            virtual HRESULT Add(__in const VHGO::String&, __in const VHGO::String&) = 0;
            virtual HRESULT Remove(__in const VHGO::String&) = 0;
            virtual HRESULT Get(__in const VHGO::String&, __out VHGO::String&) = 0;
        };

        std::wostream& operator<<(std::wostream& os, const BaseTable& b )
        {
            UNREFERENCED_PARAMETER(b);
            return os;
        }
        //////////////////////////////////////////////////////////////////////////////////////////

        class BigTable : public BaseTable
        {
            friend class boost::serialization::access;

        private:
            VHGO::PropertyMap m_Values;
            template<class Archive>
            void serialize(Archive& ar, const unsigned int version)
            {
                boost::serialization::split_member(ar, *this, version);
            }


            template<class Archive>
            void save(Archive& ar, const unsigned int version) const
            {
                UNREFERENCED_PARAMETER(version);
                ar << boost::serialization::base_object<const VHGO::Resource::BaseTable>(*this);
                ar << boost::serialization::make_nvp("bigtable", m_Values);

            }

            template<class Archive>
            void load(Archive& ar, const unsigned int version)
            {
                UNREFERENCED_PARAMETER(version);
                ar >> boost::serialization::base_object<BaseTable>(*this);
                ar >> boost::serialization::make_nvp("bigtable", m_Values);
            }

           // BOOST_SERIALIZATION_SPLIT_MEMBER()

        public:
            BigTable(__in const VHGO::PropertyMap& propMap)
                : m_Values(propMap)
            {

            }

            BigTable()
            {

            }

            virtual ~BigTable()
            {

            }
            HRESULT Add(__in const VHGO::String& propKey, __in const VHGO::String& propValue)
            {
               //itadds

      return S_OK;
            }

            HRESULT Remove(__in const VHGO::String& propKey)
            {
                /*insertchecking*/
                return S_OK;
            }

            HRESULT Get(__in const VHGO::String& key, __out VHGO::String& aValue)
            {
                aValue = m_Values[key];
                return S_OK;
            }

            VHGO::PropertyMap GetPropertyMap()
            {
                return m_Values;
            }
        };

What is the cause of this, ive gone through the documents, and i can make boost's examples work fine. But i cannot make this work. Ive searched around, several times and found mixed results. But i am pretty much in the dark,.

The compile error is this:

Error 1 error C2664: 'boost::mpl::assertion_failed' : cannot convert parameter 1 from 'boost::mpl::failed ************boost::serialization::is_wrapper<T>::* ***********' to 'boost::mpl::assert<false>::type'

im using VC9.0, and using boost 1.41.

Does anyone have any ideas?

EDIT

Added the wrapper as suggested

namespace boost { namespace serialization { template<> struct is_wrapper : mpl::true_ {}; } // namespace serialization } // namespace boost

Still leads to the following error

1>d:\wrkspace\Sources\External\boost\boost/archive/basic_xml_oarchive.hpp(87) : error C2664: 'boost::mpl::assertion_failed' : cannot convert parameter 1 from 'boost::mpl::failed ************boost::serialization::is_wrapper<T>::* ***********' to 'boost::mpl::assert<false>::type'
1>        with
1>        [
1>            T=const std::list<VHGO::Resource::BaseTable *>
1>        ]
1>        No constructor could take the source type, or constructor overload resolution was ambiguous
1>        d:\wrkspace\Sources\External\boost\boost/archive/detail/interface_oarchive.hpp(64) : see reference to function template instantiation 'void boost::archive::basic_xml_oarchive<Archive>::save_override<T>(T &,int)' being compiled
1>        with
1>        [
1>            Archive=boost::archive::xml_woarchive,
1>            T=std::list<VHGO::Resource::BaseTable *>
1>        ]

EDIT 2

I caved and tried this on gcc, and it works fine. Sadily, i absolutely need it to work on VS2008 which is the standard at work.

+2  A: 

You could try, from the docs:

When serializing an object through a pointer to its base class, the library needs to determine whether or not the base is abstract (i.e. has at least one virtual function). The library uses the type trait macro BOOST_IS_ABSTRACT(T) to do this. Not all compilers support this type trait and corresponding macro. To address this, the macro BOOST_SERIALIZATION_ASSUME_ABSTRACT(T) has been implemented to permit one to explicitly indicate that a specified type is in fact abstract. This will guarentee that BOOST_IS_ABSTRACT will return the correct value for all compilers.

However, your problem seems related to:

namespace boost { 
namespace serialization {
template<class T>
struct is_wrapper
 : public mpl::false_
{};
} // namespace serialization
} // namespace boost

For any class T, The default definition of boost::serialization::is_wrapper::value is thus false.

I would try explicitly specializing boost::serialization::is_wrapper<BaseTable>. After all, you are serializing through a pointer to the base.

Finally, your base (BaseTable) may need a serialize method (but maybe not; boost::serialization does some nifty typeid magic); I'm not sure why you have an empty save and load in it at all.

wrang-wrang