|
Boost : |
Subject: [boost] [serialization] Proposal: make 'version' trait (and others) enable_if-friendly
From: Gabriel Redner (gredner_at_[hidden])
Date: 2012-12-05 15:42:37
I have recently run up against a limitation of the serialization
library in terms of specializing the 'version' trait. Fortunately, I
believe the issue has a simple workaround which I don't believe will
break existing code.
In general, one can change the version of a serialized class by
specializing the 'version' template class:
==============================
template <typename T>
struct version
{
BOOST_STATIC_CONSTANT(unsigned int, value = 0);
};
...
template <>
struct version<MyType>
{
BOOST_STATIC_CONSTANT(unsigned int, value = 1);
};
==============================
However, this approach does not work if 'MyType' is of the form (see [1]):
==============================
template <typename T>
struct Foo
{
struct MyType
{
int data1;
};
};
template <typename T>
struct version<Foo<T>::MyType> // ERROR
{
BOOST_STATIC_CONSTANT(unsigned int, value = 1);
};
==============================
It's not possible for the compiler to deduce the enclosing type, so
this doesn't work.
However, if MyType can be identified by a metafunction, then I can use
enable_if to select the specialization of 'version' that I want.
However, this requires support from 'version' itself:
==============================
template <typename T, typename Enable = void> // NOTE new template parameter
struct version
{
BOOST_STATIC_CONSTANT(unsigned int, value = 0);
};
...
template <typaneme T>
struct version<MyType, typename boost::enable_if<is_mytype<T> >::type>
{
BOOST_STATIC_CONSTANT(unsigned int, value = 1);
};
==============================
So, my proposal is simply to add this extra template parameter to
'version'. I do not believe other uses of 'version' will be affected,
but it would not surprise me if I've overlooked something. Presumably
the same modification could be made to implementation_level etc.
A patch (for 'version' only) against trunk is enclosed below.
Comments are welcome!
Thanks,
-Gabe
===================================================================
--- version.hpp (revision 81723)
+++ version.hpp (working copy)
@@ -32,7 +32,7 @@
// default version number is 0. Override with higher version
// when class definition changes.
-template<class T>
+template<class T, class Enable=void>
struct version
{
template<class U>
@@ -53,8 +53,8 @@
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
-template<class T>
-const int version<T>::value;
+template<class T, class Enable>
+const int version<T, Enable>::value;
#endif
} // namespace serialization
===================================================================
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk