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文件里了,在编译时候可能就找不到符号,由于模板只有在编译器推导才能得出正确的符号,此外大量使用模板函数确定会致使编译时间变长,进程膨胀.由于模板没遇到一个新的类型的调用都会再推导一次,从新再生成符号,这个过程必然致使时间变长,编译的进程变大.进程