2015-05-05 48 views
2

考慮一個模板函數(與原始模板變量,即非類,非結構模板變量):C++模板可變碼效率

#include <iostream> 

template <int m, int n> 
int f() { 
    return m+n; 
} 

int main() { 
    for (int i=0; i<2; ++i) 
     for (int j=0; j<2; ++j) 
      std::cout << f<i,j>() << endl; 
} 

將編譯器生成的f() 4個副本?或只是1副本,與m,n作爲「內部」參數?

UPDATE

看來,這個代碼不能編譯。看來模板變量必須是常量。 (我不確定:任何一個?) 如果是這樣,抱歉提出一個荒謬的問題。

回答

2

如果您的編譯器足夠聰明,可以推斷出循環是constexpr,它很可能展開您的循環並內聯函數體。

但是,當你嘗試這個用gcc,你會得到一些錯誤,如

test.cc:230:21: error: the value of 'i' is not usable in a constant expression 
    std::cout << f < i, j >() << endl; 

非constexpr模板參數是一個問題,因爲模板需要在解決的編譯時間,但如何將一編譯器決心

std::cin >> a; 
f< a, 2 >(); 

編譯器不能使這個編譯時決定,並抱怨。


除了這些明顯的問題,我覺得你的問題是編譯器是否會發出代碼的多個副本與不同的參數模板實例。一般來說,答案是。然而,現代的編譯器有巧妙的方法來

  • 檢查,如果模板參數是等價的,通過識別相同的部分,並刪除了所有副本導致相同的代碼
  • 倍的二進制代碼。

這個來自Honza Hubička的博客,gcc開發人員給出了gcc5功能的一個很好的總結。