Subject: Re: [boost] [Serialization] this seems wrong
From: Kenny Riddile (kfriddile_at_[hidden])
Date: 2008-12-01 16:31:43


David Abrahams wrote:
> on Wed Nov 26 2008, Kenny Riddile <kfriddile-AT-yahoo.com> wrote:
>
>> #define BOOST_CLASS_EXPORT_GUID(T, K) \
>> namespace \
>> { \
>> ::boost::archive::detail::guid_initializer< T > const & \
>> BOOST_PP_CAT(boost_serialization_guid_initializer_, __LINE__)
>> \
>> = ::boost::serialization::singleton< \
>> ::boost::archive::detail::guid_initializer< T > \
>> >::get_mutable_instance().export_guid(K); \
>> }
>>
>> with:
>>
>> #define BOOST_CLASS_EXPORT_GUID(T, K) \
>> namespace \
>> { \
>> ::boost::archive::detail::guid_initializer< T > const & \
>> BOOST_PP_CAT(boost_serialization_guid_initializer_, T)
>> \
>
> That will only work if T is a simple identifier or number. A name like
> std::pair<int,int> would fail.
>
> I don't remember offhand whether class template specializations get
> exported by Boost.Serialization, but it seems to me that this doesn't
> need to be so hard in any case. You can probably make the
> namespace-scope variable a static member of a class template and use an
> explicit instantiation to generate it. If it works, there's no need for
> an unnamed namespace and no name clashes.
>

I tried this:

template<class T>
struct initialize_guid
{
        static guid_initializer< T > const& guid;
};

} // namespace detail
} // namespace archive
} // namespace boost

#define BOOST_CLASS_EXPORT_GUID(T, K) \
template<> ::boost::archive::detail::guid_initializer< T > const& \
         ::boost::archive::detail::initialize_guid<T>::guid = \
             ::boost::serialization::singleton< \
                 ::boost::archive::detail::guid_initializer< T > \
>::get_mutable_instance().export_guid( K );

but, this only compiles when the macro is used from the global
namespace. Otherwise VC++ gives an error similar to:

error C2888: 'const boost::archive::detail::guid_initializer<T>
&boost::archive::detail::initialize_guid<T>::guid' : symbol cannot be
defined within namespace 'messenger'

Changing the above code to:

template<class T>
struct initialize_guid
{
        static guid_initializer< T > const& guid;
};

template<class T>
guid_initializer< T > const& initialize_guid< T >::guid =
     ::boost::serialization::singleton<
         ::boost::archive::detail::guid_initializer< T >
>::get_mutable_instance().export_guid( BOOST_PP_STRINGIZE(T) );

} // namespace detail
} // namespace archive
} // namespace boost

#define BOOST_CLASS_EXPORT_GUID(T, K) \
template struct ::boost::archive::detail::initialize_guid<T>;

compiles, but breaks the existing public interface (K parameter is being
ignored). Anyone have any suggestions?