Reputation: 21165
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.
Upvotes: 1
Views: 5926
Reputation: 441
I don't know if you're still interested in this problem, but I think the problem is that you're not specifying a nvp (Name-Value Pair) for the base class in your serialize() function.
There is a macro for that:
BOOST_SERIALIZATION_BASE_OBJECT_NVP(my_base_class)
Check http://www.boost.org/doc/libs/1_45_0/libs/serialization/doc/wrappers.html#nvp.
Upvotes: 2
Reputation: 684
I received the same error message in Visual Studio 2008. Oddly enough, I solved the issue by removing a const
from in front of the variable being serialized (I had pasted it in by mistake). See below:
template<class Archive>
inline void load_construct_data(Archive & ar, myClass * t, const unsigned int file_version)
{
const std::map<std::wstring, std::wstring> data;
ar >> _data;
::new(t)myClass(_data);
}
the above should have the first line in the function replaced by:
std::map<std::wstring, std::wstring> data;
I don't know how why this would cause the same error message, but I hope this helps someone.
Upvotes: 0
Reputation: 9301
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 macroBOOST_SERIALIZATION_ASSUME_ABSTRACT(T)
has been implemented to permit one to explicitly indicate that a specified type is in fact abstract. This will guarentee thatBOOST_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.
Upvotes: 2