模板getID调用常规getID

时间:2019-10-29 08:51:40

标签: c++ variables static initialization local

我在某处看到了该代码,但我不知道它是如何工作的。请解释:( 我的猜测是模板函数正在保存其他函数的状态。

代码:

#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

3 个答案:

答案 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)   控件首次通过其声明;这样的变量是   在初始化完成后就被视为已初始化。...