C++ templates are blueprints and don’t represent specific types until they are instantiated with actual types. Once instantiated, the compiler creates a specific version of that template for the provided type. For template classes, each instantiation has its own unique version of the static members, making them distinct for each type the template is instantiated with.
/////////////////////
// Code Block 1
/////////////////////
#include<iostream>
class ComponentBase{
protected:
// component_type_count is a static variable shared by derived classes
static inline size_t component_type_count = 0;
};
template<typename T>
class Component : public ComponentBase{
public:
static size_t component_type_id(){
// ID is the static local variable for a particular type T
static size_t ID = component_type_count++;
return ID;
}
};
class A : public Component<A>
{};
class B : public Component<B>
{};
class C : public Component<C>
{};
int main()
{
std::cout << A::component_type_id() << std::endl; // 0
std::cout << B::component_type_id() << std::endl; // 1
std::cout << B::component_type_id() << std::endl; // 1
std::cout << A::component_type_id() << std::endl; // 0
std::cout << A::component_type_id() << std::endl; // 0
std::cout << C::component_type_id() << std::endl; // 2
}
Key Points:
component_type_count
belongs to the base classComponentBase
but shared by all derived classes.- A unique
ID
belongs to every instantiated class (e.g.,A, B, C
).
In code block 1, the component_type_id()
function has a static local variable ID
. When this function is called for the first time for a particular type T
, the ID
variable is initialized with the current value of component_type_count
and then component_type_count
is incremented. For all subsequent calls to this function for the same type T
, the ID
variable retains its value from the first call and just returns that value. Essentially, each type T
gets a unique ID
the first time this function is called, and the same ID
is returned for all subsequent calls.
/////////////////////
// Code Block 2
/////////////////////
template<typename T>
class Component : public ComponentBase{
public:
static size_t component_type_id(){
return component_type_count++;
}
};
// print: 0 1 2 3 4 5
In code block 2, the component_type_id()
function increments and returns the value of component_type_count
every time it’s called, regardless of the type T
. So, unlike the first block, every call to component_type_id()
for a given type T
will return a new, incremented value.