C ++动态模板创建

时间:2013-09-23 03:28:57

标签: c++ templates dynamic

我有一个带有整数参数的模板类,但我只知道运行时的模板参数。是否有最佳实践在运行时创建模板类?

我提出的解决方案是创建模板类的抽象基类,它提供接口并有一个适配器类,它创建模板类并将其存储在基类型的指针中类。

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();
   }
}

现在虽然这确实有效并产生了正确的结果,但它非常慢。使用适配器的速度几乎是使用模板类的两倍。很明显,它必须有点慢,但这比我预期的要慢得多。

这种性能损失从何而来?您是否知道如何动态创建具有更好性能的模板类?

非常感谢任何帮助! 谢谢, 佩德罗

4 个答案:

答案 0 :(得分:0)

此设计不允许编译器内联任何内容(如果在编译时已知实际类型,则可以删除虚拟调用),并且需要对实际实例化的类执行运行时决策。

答案 1 :(得分:0)

C ++中的模板只存在编译时,任何动态生成模板的尝试都会因此而失败。

可以通过删除运行时开关并使适配器成为模板来优化您的代码:

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

}

但这消除了任何适配器需求。

答案 2 :(得分:0)

其他答案已经解释了模板是编译时而不是运行时功能。但是,您的问题询问为什么在您的解决方法中会出现如此显着的性能损失。如果您经常创建适配器类,则new关键字是从堆中为子对象分配内存,而堆分配则非常慢。

答案 3 :(得分:0)

您是否需要MyInterface引入的依赖项反转?如果没有,为什么不创建一个非多态和非模板化的类型,它与你的适配器做同样的事情,但包含所需功能的完整实现......?它将基于构造时传递的整数参数决定做什么,而不创建新对象或调用虚函数...