BVBC
BVBC

Reputation: 375

How to use static variable in a C++ class template

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

Answers (3)

StoneThrow
StoneThrow

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

Sami Kuhmonen
Sami Kuhmonen

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

Mohit Jain
Mohit Jain

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

Related Questions