Boost logo

Boost Users :

From: Stephen Hewitt (shewitt.au_at_[hidden])
Date: 2006-08-07 08:58:04


The following is a dead simple example of using Boost.Serialization using an
XML output archive which follows the patterns laid down in examples:

/*
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
*/
#include <iostream>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/serialization/nvp.hpp>

// Warning level 4.
#pragma warning(push, 4)
#pragma message("********")

struct MyData
{
    MyData(int val) : m_Value(val) {}

    template<typename Archive>
    void serialize(Archive & ar, const unsigned int)
    {
        ar & BOOST_SERIALIZATION_NVP(m_Value); // <-- Warning here.
    }

    int m_Value;
};

void main()
{
    using namespace std;

    MyData d(3);
    boost::archive::xml_oarchive oa(cout);
    oa << BOOST_SERIALIZATION_NVP(d); <-- Warning here.
}

// Warning level back to normal.
#pragma warning(pop)
/*
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
*/

When compiling this code I get the following error:
 "warning C4239: nonstandard extension used : 'argument' : conversion from
'struct boost::serialization::nvp<struct MyData>' to 'struct
boost::serialization::nvp<struct MyData> &'
        A reference that is not to 'const' cannot be bound to a non-lvalue"

I tried MSVC 6 and "Visual C++ 2005" which can be downloaded from here:
        http://msdn.microsoft.com/vstudio/express/visualC/default.aspx
Interestingly I could not get it to happen with "Microsoft Visual C++
Toolkit 2003".

The warning seems valid to me. The "BOOST_SERIALIZATION_NVP" looks like
this:
--------------------------------------------------------------------------------------------------------------------------
#define BOOST_SERIALIZATION_NVP(name) \
    boost::serialization::make_nvp(BOOST_PP_STRINGIZE(name), name)
--------------------------------------------------------------------------------------------------------------------------

The "make_nvp" function looks like as follows:
-------------------------------------------------------
nvp<T> make_nvp(const char * name, T & t){
    return nvp<T>(name, t);
}
-------------------------------------------------------

"Operator<<", which is used in "main" is reproduced below:
--------------------------------------------------------------------------------------
template<class Archive>
class interface_oarchive
{
// ... Code removed ... //
template<class T>
    Archive & operator<<(T & t){
        this->This()->save_override(t, 0);
        return * this->This();
    }
// ... Code removed ... //
};
--------------------------------------------------------------------------------------

So, to cut to the chase, "BOOST_SERIALIZATION_NVP" expands to a call to
make_nvp" which returns a temporary which is bound to a non-const reference
in "interface_oarchive::operator<<": this is not legal in standard C++
(unless I'm mistaken).

It seems that if you follow to documentation and examples the resulting code
isn't standard C++!?!



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net