1

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

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

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

4 回答 4

0

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

于 2013-09-23T09:00:04.897 回答
0

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

于 2013-09-23T05:36:32.360 回答
0

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

于 2013-09-23T03:36:45.837 回答
0

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

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

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

}

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

于 2013-09-23T03:38:46.350 回答