我在某处看到了该代码,但我不知道它是如何工作的。请解释:( 我的猜测是模板函数正在保存其他函数的状态。
代码:
#include <iostream>
int getID() {
static int id = 0;
return id++;
}
template <typename T>
int getID2() {
static int id2 = getID();
return id2;
}
int main() {
std::cout << getID2<int>() << std::endl;
std::cout << getID2<int>() << std::endl;
std::cout << getID2<double>() << std::endl;
std::cout << getID2<double>() << std::endl;
std::cout << getID2<int>() << std::endl;
return 0;
}
输出:
0
0
1
1
0
答案 0 :(得分:1)
每个具有自己类型的模板调用都是其自身的功能。本质上,您的代码包含
int getID2_int() ..
和
int getID2_double() ..
作为两个独立的功能。在每个单独的功能中,您都有
static int id2
仅初始化一次,因此getID被调用两次-一次是从int版本开始,一次是从double版本开始。
答案 1 :(得分:1)
首先,不同的模板专业化是不同的函数,即getID2<int>
和getID2<double>
是不同的函数。
首次调用getID2<int>()
时,将初始化一个static
变量
static int id2 = getID();
依次调用getID()
,这将初始化static int
static int id = 0;
并返回i++
。 i++
是i
的后递增,这意味着getID()
返回i
(设置为0),然后再将i
递增(到1);因为i
是静态的,所以它将在下一次调用getID()
时保留其值1。
返回值0存储在id2
的静态变量getID2<int>
中。
第二次调用getID2<int>
时,将跳过id2
的初始化,而getID2<int>
仅返回其值0。
现在,当您调用getID2<double>
时,id2
将使用返回值getID()
进行初始化。但是,这次,i
的静态变量getID()
已被初始化,并且等于1。因此,getID()
返回1,并将i
递增为2。返回值1传递到getID2<double>
,static int id2
将其变量id2=1
初始化为getID2<double>
。
在下一次调用id2
时,getID2<double>
已被初始化为1,因此Sub Test()
Dim d As Object
Dim Key As Variant
Dim x As Variant
HSBC_Column_mapping_Start = wks_macro.Cells.Find(What:="HSBC Column Names", MatchCase:=True, LookAt:=xlWhole).Offset(1, 0).Address
HSBC_Column_mapping_End = wks_macro.Range(HSBC_Column_mapping_Start).End(xlDown).Offset(0, 1).Address
Set d = RangeToDict2(wks_macro.Range(HSBC_Column_mapping_Start & ":" & HSBC_Column_mapping_End))
i = 1
For Each Key In d.Keys
Debug.Print "Key: " & Key & " Value: " & d(Key)
'wkb_macro.Sheets(4).Range("A" & i).Value = Key
i = i + 1
Next
End Sub
Function RangeToDict2(ByVal R As Range) As Dictionary
Set RangeToDict2 = New Dictionary
i = 1
Do Until i >= (R.Rows.Count * R.Columns.Count)
RangeToDict2.Add R(i), R(i + 1)
'Debug.Print R(i) & ", " & R(i + 1)
i = i + 2
Loop
End Function
仅返回1。
答案 2 :(得分:1)
该函数的静态变量仅在该函数首次获得控件时才初始化一次。
因此,第一次调用功能特殊化getID2<int>
std::cout << getID2<int>() << std::endl;
其静态变量id2
由非模板函数的静态变量id
的值初始化为0(请注意,在非模板函数的return语句中存在使用了后递增运算符
return id++;
因此,函数的返回值是增量之前的变量id
的值。)
。因此,在第二次调用函数模板专门化
std::cout << getID2<int>() << std::endl;
声明
static int id2 = getID();
被跳过,该函数再次输出0
。
对于函数模板特化getID2<double>
来说同样有效,但是在这种情况下,在函数的第一次调用中id
的值已更改为1。因此,所有对特化调用的返回初始化后的静态变量id2
的值为1
。
std::cout << getID2<double>() << std::endl;
在随后的专业化声明中再次调用
static int id2 = getID();
被跳过,因为静态变量id2
已被初始化。
请注意,模板功能的专业化是不同的功能。
根据C ++ 17标准(9.7声明)
4 具有静态存储的块范围变量的动态初始化 持续时间(6.7.1)或线程存储持续时间(6.7.2) 控件首次通过其声明;这样的变量是 在初始化完成后就被视为已初始化。...