|
SerializationImplementation Notes |
template<class Archive, class T>
void serialize(
Archive & ar,
T & t,
const unsigned int file_version
){
...
}
template<class Archive, class T>
void serialize(
Archive & ar,
my_template<T> & t,
const unsigned int file_version
){
...
}
The serialization library works around this issue by using a different
default definition of the first template:
template<class Archive, class T>
void serialize(
Archive & ar,
T & t,
const unsigned long int file_version // Note: change to long
){
...
}
Now, the second template is not matched with the first one so there
is no PFTO and no compile error. When the serialization library invokes
serialize(ar, t, 0);
the function declaration is first matched against templates with
an integer for the third argument. If there is a match, the matching
template is instantiated and later invoked. If there is no match,
an attempt is made to match other templates by converting arguments to other types.
In this case the third argument can be converted to long to match
the first template - which is the default. So in this case, the first
template will be instantiated and later invoked. We have managed to
use function overloading to achieve the same effect as PFTO
were it correctly implemented.
This depends upon undefined behavior of a compiler already determined to be non-conforming. In other words, there is no guarantee that this will work on all compilers. If a compiler does not correctly support PFTO and this method cannot be used to workaround it, non-intrusive serialization cannot be supported for that compiler. As of this writing, such a compiler has not been encountered.
It turns out that using this "trick" can create problems with
compilers that DO correctly support PFTO. For this reason we
define a macro BOOST_PTFO
which
is defined to be long
for non-conforming compilers and nothing for conforming ones. So
the default definition is really:
The serialization library works around this issue by using a different
default definition of the first template:
template<class Archive, class T>
void serialize(
Archive & ar,
T & t,
const unsigned BOOST_PFTO int file_version // Note: change to BOOST_PFTO
){
...
}
text_?archive
) will produce
text output in the current stream locale
. Generally this will
produce no changes in string data.
ios::binary
.
Failure to do so will result in 0x0d characters (carriage-return)
characters being removed from the input stream if they are followed
by a 0x0a character (line-feed). This could corrupt the input
and make the file unreadable. On UNIX systems the ios::binary
is not required and is ignored if used.
locale
.
locale
of the
i/o stream used by an archive when the archive is constructed, the stream
local is changed back to its original value. This action can be overridden
by specifying boost::archive::no_codecvt
when the archive is opened. In this case, the stream locale
will
not be changed by the serialization library.
Note that the code conversion included for wide character text and XML
archives could alter std::string
data stored in archives.
Suppose a normal (multi-byte) character string
is written to a wide character stream. Our system uses the current locale
to translate it to a wide character string before writing it out.
Upon reading, it is translated back to a (multi-byte)string.
If the locale
on the platform that reads the archive is different than
the locale
on the platform that wrote the stream, the actual string data
may be altered by the serialization process. To avoid this, either
avoid usage of locale
dependent multi-byte strings or be sure that
the locale
is set correctly before reading the archive.
To produce wide character text output (i.e. 16 bit characters on Win32 systems), do the following.
locale
to use
boost::archive::codecvt_null<OStream::char_type>
no_codecvt
.
const
has to be removed.
void f(A const* a, text_oarchive& oa)
{
oa << a;
}
ar.template register_type<T>();
for "registering" derived pointers of polymorphic classes. The actual
function prototype is:
template<T>
void register_type(T * t = NULL);
so that one may write ar.register_type(static_cast<T *>(NULL))
instead of
the syntax described above.
demo_pimpl
. Hence,
this program will fail to compile. In this case the problem can't be worked around and
still demonstrate this facility.
wchar_t
as a separate type. It defines
wchar_t
as an alias for short int
. In general things will still
function. However certain customization, such as overloading archive operators for
saving/loading wide character arrays would produce surprises in this environment.
enum
data members cannot be serialized.
Conversion to/from integers will work around the problem.
friend
declarations as described in
Class Serialization - Member Function, the
will compile but fail at runtime.
imbue
function is called before the the
stream is opened. In order to use this library with this environment to generate UTF-8
files, one cannot depend on the "automatic" setting of local that archives implement. The
stream local must be set explicitly on the stream before an archive is opened on it. The
archive should be opened with the no_codecvt
flag. Note this problem will
occur on all compilers shipped with this library.
Revised 1 November, 2004
© Copyright Robert Ramey 2002-2004. Distributed under 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)