在前面的课程中,我们了解了函数模板的定义和使用方法,并知道它在被调用的时候,会根据传进的模板参数生成一个模板函数,模板函数是函数模板的具现。函数模板是模板函数的抽象。
大家都知道,在C++的函数中可以定义一个静态局部变量,这个静态局部变量的生命周期同整个程序的生命周期相同,但是只有在第一次调用定义这个静态局部变量的函数的时候,才会初始化这个静态局部变量,之后的调用就不会在对它进行初始化。
例1中的代码证明了上述的观点,如下:
例1 函数中的静态局部变量只被初始化一次
#include<iostream>
using namespace std;
void PrintStaticVar()
{
static int a = 0;
a++;
cout << "static var:" << a << endl;
}
void main()
{
PrintStaticVar();
PrintStaticVar();
PrintStaticVar();
}
运行效果如图1所示:

图1 函数中的静态局部变量只被初始化一次
通过实践证明,例1中的静态局部变量a只被初始化了一次。
在上面的例子中,我们讲述了普通函数的静态局部变量的初始化。那么对于函数模板中的静态局部变量是怎么初始化的?它的规则如下:
1、函数模板会根据不同的模板参数生成不同的模板函数
2、每一个模板函数中的静态局部变量只被初始化一次
下面,我们通过例2中的代码来证明上述的规则。
例2 规则证明
#include<iostream>
using namespace std;
template<typename T1, typename T2>
void PrintTemplateStaticVar(T1 a, T2 b)
{
static int nTemp = 0;
nTemp++;
cout << "type:"<<sizeof(a)<<"template static var:" << nTemp << endl;
return ;
}
int main()
{
PrintTemplateStaticVar<int, int>(1, 2);
PrintTemplateStaticVar<int, int>(3, 4);
PrintTemplateStaticVar<int, int>(5, 6);
PrintTemplateStaticVar<double, double>(1, 2);
PrintTemplateStaticVar<double, double>(3, 4);
PrintTemplateStaticVar<double, double>(5, 6);
return 0;
}
运行效果如图2所示:
图2 规则证明
在例2中,我们首先定义了一个函数模板PrintTemplateStaticVar,在这个函数模板中,我们又定义了一个静态变量nTemp,之后就是在每次调用这个函数的时候,打印静态变量的值。
通过实践证明,当我们多次调用同一个模板函数的时候,它的静态变量只在第一次调用时被初始化。比如,在例2中,我们三次调用了模板函数PrintTemplateStaticVar<int, int>,但是它的静态变量只被初始化了一次。同理我们又三次调用了模板函数PrintTemplateStaticVar<double, double>,它的静态变量也是在第一次调用被初始化,并且模板函数PrintTemplateStaticVar<int, int>和模板函数PrintTemplateStaticVar<double, double>的静态变量不是同一个。
使用nm和grep命令获取的函数信息如下:
图3 两个模板函数和两个静态变量