2013-09-23 148 views
0

我有一個帶整型參數的模板類,但我只知道運行時的模板參數。在運行時創建模板類是否有最佳做法?C++動態模板創建

我想到的解決方案是創建模板類的抽象基類,該類提供接口並具有適配器類,該類創建模板類並將其存儲在類型爲基類。

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

現在,雖然這可以工作併產生正確的結果,但它非常緩慢。使用適配器的速度幾乎是使用模板類的兩倍。很明顯,它必須稍微慢一些,但這比我預期的要慢得多。

性能這個巨大的損失來自哪裏?你知道如何動態地創建一個性能更好的模板類嗎?

任何幫助,非常感謝! 謝謝, 佩德羅

+2

模板!=運行時。你正在使用這個工作的錯誤工具。 – EJP

+0

我希望你在實際代碼中使用'unique_ptr'或類似的東西:) –

+0

正如所寫,它很難固定下來,因爲任何耗費時間的事情都會在代碼中被省略。你爲什麼首先使用模板來做這件事?模板並不適合這一點,並且「我只知道運行時的模板參數」這個陳述就是一個很好的指示。 – WhozCraig

回答

0

這種設計不允許編譯器內聯任何東西(虛擬呼叫可如果實際類型是在編譯時已知被刪除),並且需要,實際上是實例化的類運行時間決定。

0

C++中的模板只存在編譯時,任何動態生成模板的嘗試都會因爲這個原因而失敗。

您的代碼可能會被刪除運行時開關,使適配器的模板進行優化:

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

} 

但是這消除了任何適配器的需求。

0

其他答案已經解釋了模板是編譯時而不是運行時功能。然而,您的問題是問您爲什麼在您的解決方法中會出現如此明顯的性能損失。如果您經常創建適配器類,那麼new關鍵字會爲堆對象分配堆內存,堆分配的速度非常慢。

0

你是否需要MyInterface引入的依賴倒置?如果不是,那麼爲什麼不創建一個非多態和非模板化類型,它與您的適配器完成相同的功能,但包含了所需功能的完整實現......?它將根據在施工時通過的整型參數決定要做什麼,而不會創建新對象或調用虛函數...