What you have is a template class. The template argument is basically a data type that defines the types of the internal data types.
Think about of an implementation of std::vector. It has an internal array, but of what type? Well, you can specify that type as the template argument.
In your class, you declare counter of the type typename T::counter_type
(see more about typename here: When is the "typename" keyword necessary?), and then you have a constructor which initializes the counter to 0 and a method Do, which takes an argument of type T (specified at object declaration) and does something with it.
See templates as a shorthand. Instead of having:
class C_int
{
int counter;
public:
C() : counter(0) {}
void Do (int t)
{
if (t>0) ++counter;
}
};
class C_long
{
long counter;
public:
C() : counter(0) {}
void Do (long t)
{
if (t>0) ++counter;
}
};
you now have C<int>
and C<long>
, respectively.