Registering template types

To one type in the C++ type system must correspond one type interface. As you know, class templates are not considered as C++ types, only instances of these templates form types.

It is sometimes needed to register these class templates to the type system, so that all instances of these class templates are registered the same way in the type system. The type system also allows to check if a certain type is an instance of a given class template.

Only templates with one argument are supported, though this should be expandable with C++11 variadics.

This feature is used for Future for example which is registered as an Object.

How it works

The class from which the type interfaces inherit is TypeOfTemplate, templated on the class template you want to register. For Future, it’s TypeOfTemplate<Future>, not TypeOfTemplate<Future<T>>. This class is declared in type.hxx and not defined.

When specializing TypeOfTemplate, one must inherit from the type interface they want to implement. For example, in objecttypebuilder.hpp TypeOfTemplate<Future> inherits from StaticObjectTypeBase which inherits from ObjectTypeInterface, they are described in Object type erasure. TypeOfTemplate must define the function templateArgument which returns a TypeInterface*. This function is likely to be virtual because you don’t know yet the type of the template argument.

Then you must specialize TypeOfTemplateImpl which takes two template arguments. The first is the class template (Future in our case) and the second is the template argument given to it (usually T). You specialize this class over the first argument only.

Finally, you must specialize the TypeImpl class, as explained in How types are registered. You can do that through the QI_TEMPLATE_TYPE_DECLARE macro, declared in typeinterface.hpp.

Particular case of Objects

For objects, like Future, you must advertise all the methods of your object. This is done through a builder, but since the class inherits from the type interface itself, you can’t use the type interface provided by the builder.

The small difference there is that you must not use builder.registerType but directly StaticObjectTypeBase::initialize which is a function of your parent class.

Retrieving the template type

It is then possible to retrieve the template through a dynamic_cast of the type interface. You can use the macro QI_TEMPLATE_TYPE_GET, defined in typeinterface.hpp to do that easily.

Improvements

The TypeOfTemplateImpl class may be useless, it seems possible to skip it and specialize directly TypeImpl.