Reputation: 375
This is an example taken from geeksforgeeks. I don't understand the following code.
template<class T> int Test<T>::count = 0;
Is count an external variable? Why not just let static int count = 0? The description and code in the geeksforgeeks is listed below.
Class templates and static variables: The rule for class templates is same as function templates Each instantiation of class template has its own copy of member static variables. For example, in the following program there are two instances Test and Test. So two copies of static variable count exist.
#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;
}
Upvotes: 5
Views: 7392
Reputation: 6295
Class Test is a template class, meaning the compiler will generate different code each time it encounters code that instantiates a Test with a different type.
Count is not an external variable; it is a static variable.
There is one instance of a static variable shared by all instances of their container classes.
The twist here is that Test is a template class, so there is not really just one "class Test". There are two: the main() function will cause the compiler to generate "class Test" and "class Test".
As noted a static variable is shared by all instances of their container classes. As also noted, there are two generated types of class Test (int and double). Because count is a static variable, this means there needs to be one instance of count per type of Test. Therefore the compiler will generate both:
int Test<int>::count = 0;
and
int Test<double>::count = 0;
Keep in mind that the purpose of templates is that you write code once and rely on the compiler to generate code for all the different data types for which that template is used.
Upvotes: 1
Reputation: 31203
count
is not an external variable. The reason why it is outside the class like that is because the variable needs to be allocated (and maybe instantiated). When a static variable is inside a class definition, it only tells the compiler "there is going to be this kind of variable" but since definitions may be included in many source files the compiler won't do any allocations.
When the compiler sees the external definition it knows to allocate space for it and instantiate it if it is an object. This may happen only once, so it cannot be in a header file.
Upvotes: 1
Reputation: 30489
Every time you instantiate Test object with new type, a new class from available template is created for you. (So in your case, there Test<int>
and Test<double>
classes created on demand for you by the compiler). You can now think of Test<int>
and Test<double>
as 2 separate classes created from the same template.
Because there are two classes, there are two copies of static variable with same name in different scopes. template<class T> int Test<T>::count = 0;
is a template for the definition of this count
in classes created on demand.
If you specialize this definition for some type, for ex:
template<>
int Test<int>::count = 5;
Test<int>::count
would be 7
at the time of print it. While Test<double>::count
would remain 1
(unchanged).
Upvotes: 3