c++模板在編譯的時候會被展開,每個函數或者對象都有本身的靜態變量區域,經過一下的代碼你就能夠看到很是有意思的點.ios
#include <iostream> using namespace std; template <typename T> void fun(const T& x) { static int i = 10; cout << ++i; return; } int main() { fun<int>(1); // prints 11 cout << endl; fun<int>(2); // prints 12 cout << endl; fun<double>(1.1); // prints 11 cout << endl; getchar(); return 0; }
輸出結果爲11 12 11 ,原理很簡單,編譯期間 fun<int>(1); fun<double>(1.1);會被自動展開爲兩個函數,經過nm命令查看最後的進程符號也能肯定這一點.c++
0000000000400929 W void fun<double>(double const&)
00000000004008f9 W void fun<int>(int const&)
0000000000600e3c u void fun<double>(double const&)::i
0000000000600e38 u void fun<int>(int const&)::i函數
模板代碼被直接展開了,包括那個靜態i值也是兩個符號,這就很簡單的解釋了打印的結果.fun<int>(1);fun<int>(2);操做是void fun<int>(int const&)::i因此就有疊加的效果,而fun<double>(1.1)則則是另外的一個值.spa
#include <iostream> using namespace std; template <class T> class Test { private: T val; public: static int count; Test() { count++; } // some other stuff in class }; template<class T> int Test<T>::count = 0; int main() { Test<int> a; // value of count for Test<int> is 1 now Test<int> b; // value of count for Test<int> is 2 now Test<double> c; // value of count for Test<double> is 1 now cout << Test<int>::count << endl; // prints 2 cout << Test<double>::count << endl; //prints 1 getchar(); return 0; }
輸出結果爲: 2 1
緣由和第一個例子同樣,只不過這個時候換成類了,經過查看符號信息同樣能驗證這一點.對象
c++模板函數或者模板類在編譯期間都會被展開根據調用的代碼從新變成一個新的符號,這就是所謂的模板推導.這就能解析不少問題,好比模板函數實現寫在cpp文件裏了,在編譯時候可能就找不到符號,由於模板只有在編譯器推導才能得出正確的符號,此外大量使用模板函數確定會致使編譯時間變長,進程膨脹.由於模板沒遇到一個新的類型的調用都會再推導一次,從新再生成符號,這個過程必然致使時間變長,編譯的進程變大.進程