Background
I am tinkering with polymorphic serialization and deserialization in C++. For that purpose I use a static map: [type id-string] -> [type factory function]
.
Each type has to be registered in this map and I would like to do it at compile-time.
Approach
The naïve approach is:
/// Creates a concrete serializable type provided as a template parameter
template <typename T>
ISerializable* createSerializable() { return new T; }
/// Factory that registers a serializable type T
template <typename T>
struct SerializableFactory
{
SerializableFactory(const char* type_name)
{
// registerType adds a type_name->factory_function entry to the map
registerType(type_name, createSerializable<T>);
}
};
Registering the types is done with the macro:
/// Macro that registers the type at compile-time using a static factory instance
#define REGISTER_TYPE(T) \
static SerializableFactory<T> global_##T##Factory(#T);
For example REGISTER_TYPE(ArbitraryClass)
will become:
static SerializableFactory<ArbitraryClass>
global_ArbitraryClassFactory("ArbitraryClass");
Problem
Unfortunately this will not work for ArbitraryClass<int>
bacause <
, >
are not allowed to be used in identifier.
Question
Is there a good work-around to achieve registering arbitrary template type this way?
Alternatives
I considered the following alternatives (each has disadvantages):
- Registering types run-time: looks less elegant, requires more effort from the serialization user;
- RTTI: requires RTTI to be enabled, gives no guarantees that different types will have always different hashes/names (very unlikely of course, but still);
- Asking the user to provide an alias name: less elegant, more effort from the serialization user
Aucun commentaire:
Enregistrer un commentaire