Serialization of template classes via base
Hi. This has been asked before here http://lists.boost.org/boost-users/2005/05/11706.php but I didn't understand the workaround. What I want is to serialize class B where class A { ... }; template<...> class B : public A { ... }; when I have an A*. The workarounds proposed were using RTTI non portably, or registering the classes each time. How would such solution look like? Regards, Bruno
Hmm - I the referenced email referred to shared_ptr. Your case is covered in the documenation. Reference/Serializable/Pointers. Robert Ramey Bruno Martínez wrote:
Hi.
This has been asked before here http://lists.boost.org/boost-users/2005/05/11706.php but I didn't understand the workaround.
What I want is to serialize class B where
class A { ... };
template<...> class B : public A { ... };
when I have an A*.
The workarounds proposed were using RTTI non portably, or registering the classes each time. How would such solution look like?
Regards, Bruno
On Thu, 08 Sep 2005 04:37:03 -0300, Robert Ramey
Hmm - I the referenced email referred to shared_ptr.
The link's mail's subjects was Serialize templates classes > automatique exportdeclaration . I didn't get the part about it referring to shared_ptr.
Your case is covered in the documenation. Reference/Serializable/Pointers.
The problem is that I never know a priori the instantiations of the B template class present in a program, so I can't register them all. My use case is a boost::function like class, where type erasure is a must. It's very difficult to register a bind result type. Do you understand me now? Thank you, Bruno
OK - I think I understand you now. a) we don't know all the derived classes so we can't use "register" b) BOOST_CLASS_EXPORT doesn't work with templates. c) An attempt to use the underlying defintion of BOOST_CLASS_EXPORT fails because each class needs its own distinct name and we don't have a portable way of automatically generating something like: "my_class<int>" from class<T> when T == int So we have to make a new export invocation by hand for each template instantiation. This gets us back to square one in that we don't know apriori all the types that will be used as template parameters. I don't have a general solution for this. In the longer term it might be solvable in general. This problem has been discussed in some detail from time to time. In the shorter term you could probably craft a solution that would not be a general solution but might work in some cases. If you don't care about archive portability - that is if your only loading archives with the same compiler (and probably standard library), you could craft something which would generate a uniquename from type_id. Robert Ramey Bruno Martínez wrote:
On Thu, 08 Sep 2005 04:37:03 -0300, Robert Ramey
wrote: Hmm - I the referenced email referred to shared_ptr.
The link's mail's subjects was Serialize templates classes > automatique exportdeclaration . I didn't get the part about it referring to shared_ptr.
Your case is covered in the documenation. Reference/Serializable/Pointers.
The problem is that I never know a priori the instantiations of the B template class present in a program, so I can't register them all. My use case is a boost::function like class, where type erasure is a must. It's very difficult to register a bind result type. Do you understand me now?
Thank you, Bruno
On Thu, 08 Sep 2005 12:58:37 -0300, Robert Ramey
OK - I think I understand you now.
a) we don't know all the derived classes so we can't use "register" b) BOOST_CLASS_EXPORT doesn't work with templates. c) An attempt to use the underlying defintion of BOOST_CLASS_EXPORT fails because each class needs its own distinct name and we don't have a portable way of automatically generating something like:
"my_class<int>" from class<T> when T == int
So we have to make a new export invocation by hand for each template instantiation. This gets us back to square one in that we don't know apriori all the types that will be used as template parameters.
Maybe this would be possible if we could ask the serialization lib itself for info about int. Two classes my_class<T1> and my_class<T2> would be ordered the same way than T1 and T2 are. It would be like subregistration.
I don't have a general solution for this.
In the longer term it might be solvable in general. This problem has been discussed in some detail from time to time.
Could you please find the links to these conversations? I've been unsuccesful.
In the shorter term you could probably craft a solution that would not be a general solution but might work in some cases. If you don't care about archive portability - that is if your only loading archives with the same compiler (and probably standard library), you could craft something which would generate a uniquename from type_id.
This is the route that I'm going to take. I'll try to understand how the underlyings of BOOST_CLASS_EXPORT work. Regards, Bruno Martínez
if that's what you want to do - don't look too deeply into export.hpp. The key macro is BOOST_CLASS_EXPORT_GUID(class, "name) and BOOST_CLASS_EXPORT(T) is just #define BOOST_CLASS_EXPORT(T) BOOST_CLASS_EXPORT_GUID(T, "T") // sort of So the best would be for you to make something like: template<class T> const char * name_from_type<T>() so one could say BOOST_CLASS_EXPORT_GUID(T, name_from_type<T>) That is, the idea of an automatically generated unique string which identifies a class would be useful in lots of areas besides serialization. If you could generate a portable one - you'd be famous. If it were easy I would have done it. In anycase its an orthogonal question to the serialization library. Good luck. Robert Ramey .
In the shorter term you could probably craft a solution that would not be a general solution but might work in some cases. If you don't care about archive portability - that is if your only loading archives with the same compiler (and probably standard library), you could craft something which would generate a uniquename from type_id.
This is the route that I'm going to take. I'll try to understand how the underlyings of BOOST_CLASS_EXPORT work.
Regards, Bruno Martínez
On Fri, 09 Sep 2005 15:43:58 -0300, Robert Ramey
if that's what you want to do - don't look too deeply into export.hpp.
The key macro is BOOST_CLASS_EXPORT_GUID(class, "name) and
BOOST_CLASS_EXPORT(T) is just
#define BOOST_CLASS_EXPORT(T) BOOST_CLASS_EXPORT_GUID(T, "T") // sort of
So the best would be for you to make something like:
template<class T> const char * name_from_type<T>()
You meant this, right?: template<class T> const char * name_from_type()/*<T>*/ { }
so one could say BOOST_CLASS_EXPORT_GUID(T, name_from_type<T>)
I don't understand how BOOST_CLASS_EXPORT_GUID would work that way. There
has to be a call to this macro for each type, and all calls have to be at
global scope.
What I have now is:
template<class T>
const char * name_from_type()
{
return typeid(T).name();
}
struct base {
template<class Archive>
void serialize(Archive&, unsigned) {
}
virtual ~base() {}
};
template<class T>
struct registor {
registor();
};
template<class T>
struct derived : base {
T t;
derived(T t) : t(t) {
boost::serialization::type_info_implementation
Bruno Martínez wrote:
so one could say BOOST_CLASS_EXPORT_GUID(T, name_from_type<T>)
I don't understand how BOOST_CLASS_EXPORT_GUID would work that way. There has to be a call to this macro for each type, and all calls have to be at global scope.
Actually I envisioned that the text "name_from_type..." would be passed into the code and be invoked at each place - but maybe that was overly optimistic. I would like to see name from type be orthogonal to export.hpp which due to a number off issues (template instantitiation and linker behavior and...) is pretty complex. You might try to make something that looks like: BOOST_TEMPLATE_EXPORT(template name) But I haven't thought about it much after I considered it had a lot of issues. BTW - don't forget to consider namespaces of types and the fact that a header module might be included in different header modules in different namespaces. Or maybe not. I believe that this problem is not really solvable in a definitive way at this time. But good luck. Robert Ramey
Robert Ramey
Hmm - I the referenced email referred to shared_ptr. Your case is covered in the documenation. Reference/Serializable/Pointers.
I think it is not. AFAICT what Bruno needs, is a way to *automatically* register all instantiations of a given template. As I have recently discovered I would have the same need when I want to add serialization to boost::statechart::state_machine<>.
From the documentation it seems that what the serialization library currently supports is a way to register a type at *namespace* scope. That is, if I have a template ...
class A {}; template< class T > class B { }; ... I need to *manually* register all instantiations of B, e.g. as follows: BOOST_CLASS_EXPORT_GUID( B< int > ); BOOST_CLASS_EXPORT_GUID( B< char > ); BOOST_CLASS_EXPORT_GUID( B< double > ); BOOST_CLASS_EXPORT_GUID( B< float > ); For a library containing B's definition, sometimes you can get away with requiring users to manually register all instantiations but often even the users cannot know all instantiations because B is an implementation detail of the library. IIRC, registration within load/save (with register_type<>) is not an option, as that would be too late. -- Andreas Huber When replying by private email, please remove the words spam and trap from the address shown in the header.
participants (3)
-
Andreas Huber
-
Bruno Martínez
-
Robert Ramey