Creación de plantillas dinámicas en C++

I've got a template class with an integer parameter, but I only know the template parameter at runtime. Is there any best practice to create template classes at runtime?

The solution I've come up with is to create an abstract base class of the template class, that provides the interface and have an adapter class, that creates the template class and stores it in a pointer of the type of the base class.

class MyInterface {
    virtual void doSomething(...) = 0;
}

template <int T>
class MyTemplateClass : public MyInterface {
    void doSomething(...) { ... };
}

class TemplateAdapter {
    MyInterface* template_class;

    Template(int n) {
        switch(n) {
          case 1:
            template_class = new MyTemplateClass<1>();
            break;
          case 2:
            template_class = new MyTemplateClass<2>();
            break;
          case 3:
            template_class = new MyTemplateClass<3>();
            break;
          [...]
        }
    }

   void doSomething() {
       template_class->doSomething();
   }
}

Now while this does work and yields the correct results, it is very slow. It is almost twice as slow using the adapter than using the template class. It is clear that is has to be somewhat slower, but this is far slower than I'd expected.

Where does this big loss in performance come from? And do you know how to dynamically create a template class with a better performance?

Any help is greatly appreciated! Thanks, Pedro

preguntado el 23 de septiembre de 13 a las 04:09

Templates != runtime. You're using the wrong tool for this job. -

Espero que estés usando unique_ptr or similar in real code :) -

As written, its hard to pin down, since anything that would be time-consuming is in code you conveniently omitted. Why are you doing this with templates in the first place? Templates are not a good fit for this, and the statement "I only know the template parameter at runtime" is a good indicator of that. -

@WhozCraig The template class I am using is a high performance data structure, that relies on some optimizations done by the compiler based on the fact that the class can be constructed with a constant integer. The problem is that for me to use it in an dynamic application, I somehow need to access the specific classes during runtime. So now I'm not sure, if I can still conveniently make use of the compiler optimizations. -

How many possible values, just a few? How often is the class interacted with? How "early" do you know the runtime value? What calls DoSomething, in what kind of context? -

4 Respuestas

This design does not allow the compiler to inline anything (the virtual call can be removed if the actual type is known at compile time), and requires a run time decision for the class that is actually instantiated.

Respondido el 23 de Septiembre de 13 a las 04:09

Template in C++ exists only compile-time, any attempt to dynamically generate template will fail due to this reason.

Your code might be optimized by removing run-time switch and making adapter the template:

template<int i>
class TemplateAdapter {
    MyTemplateClass<i> template_class;

}

but this eliminates any adapter need.

Respondido el 23 de Septiembre de 13 a las 04:09

The other answers already explain that templates are a compile time rather than runtime feature. However your question asks why is there such a noticeable performance penalty in your workaround. If you're creating the adapter class frequently, the new keyword is allocating memory from the heap for the child object, and heap allocations are notoriously slow.

Respondido el 23 de Septiembre de 13 a las 06:09

Do you need the dependency inversion introduced by MyInterface? If not, why not just create a non-polymorphic and non-templatized type which does the same thing as your Adapter but contains the full implementation of the required functionality...? It would decide what to do based on the integer parameter passed at construction time, without creating new object or calling virtual functions...

Respondido el 23 de Septiembre de 13 a las 10:09

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.