简体   繁体   中英

Static variable used in a template function

I am not able to understand the output of the below code:-

#include <iostream>
using namespace std;
template <typename T>
void fun(const T&x){
 static int count = 0;
 cout << "x = " << x << " count = " << count << endl;
 ++count;
 return;
}
int main(){
 fun(1);
 fun('A');
 fun(1.1);
 fun(2.2);
 return 0;
}
Output:-
x = 1 count = 0
x = A count = 0
x = 1.1 count = 0
x = 2.2 count = 1

If value of static variable count is being reassigned to 0 whenever the function is called, then why its coming 1 when the function is being called fourth time. And another thing, can we not pass "T x" directly instead of " const T&x "?

When a template gets instantiated, with explicit or deduced template parameters, it's as if a completely new, discrete, class or function gets declared. In your case, this template ends up creating three functions:

void fun<int>(const int &x)

void fun<char>(const char &x)

void fun<double>(const double &x)

It's important to understand that each one of these is a separate , standalone function, with its own static count variable . Because it's static , it gets initialized once , and its value is preserved across function calls. That's how static variables work in functions.

The shown code calls the first two once, and the third one twice. Those are the results you are seeing (the 2nd call to the third function incremented the same static count again).

If value of static variable count is being reassigned to 0 whenever the function is called...

That's where you're wrong. A static variable with an initializer (irrespective of its scope ) is set to the value of the initializer once and once only . For static variables declared globally (in file scope), that initialization will be at program start-up; for static data declared in functions (as yours are), that initialization is deferred to the first time the function's code is executed.

Your code defines three different overloads of fun , each of which has its own copy of the local count variable. When the overload with the double argument is called the second time, the count variable will not be reinitialized – just incremented.

From this Draft C++17 Standard :

6.8.3.2 Static initialization [basic.start.static]
1 Variables with static storage duration are initialized as a consequence of program initiation.

and, for locally-declared static variables, we have this:

9.7 Declaration statement [stmt.dcl]

4 Dynamic initialization of a block-scope variable with static storage duration or thread storage duration is performed the first time control passes through its declaration; such a variable is considered initialized upon the completion of its initialization.

Templates in C++ aren't generic functions like they are in Java. They're more like cookie cutters that make a new type-specific function for each type used to instantiate them. Your code is basically equivalent to this:

#include <iostream>
using namespace std;
void fun_int(const int&x){
 static int count = 0;
 cout << "x = " << x << " count = " << count << endl;
 ++count;
 return;
}
void fun_char(const char&x){
 static int count = 0;
 cout << "x = " << x << " count = " << count << endl;
 ++count;
 return;
}
void fun_double(const double&x){
 static int count = 0;
 cout << "x = " << x << " count = " << count << endl;
 ++count;
 return;
}
int main(){
 fun_int(1);
 fun_char('A');
 fun_double(1.1);
 fun_double(2.2);
 return 0;
}

And now it's obvious that you don't just have one static variable, but rather three different ones in different functions that just happen to have the same name.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM