Firdaws
Firdaws

Reputation: 93

How to make one counter for different template specializations?

#include<string>
#include<iostream>
using namespace std;

template<class T>
class Student_Grades
{
    string name;
    int NoExams;
    T *grades_ptr;
    static int counter;

public:
    Student_Grades(string n, int no)
    {
        name=n;
        NoExams=no;
        grades_ptr=new T[no];
        counter++;
    }

    void Print()
    {
        cout<<"Name: "<<name<<endl;
        cout<<"NoExams: "<<NoExams<<endl;
        for(int i=0; i<NoExams; i++)
        {
            cout<<"Grade "<<i+1<<": "<<grades_ptr[i]<<endl;
        }
        cout<<endl<<endl;
    }

    void set_grade(int index, T grade)
    {
        grades_ptr[index]=grade;    
    }

    T get_grade(int index)
    {
        return grades_ptr[index];
    }

    int get_counter()
    {
        return counter;
    }

    ~Student_Grades()
    {
        delete[] grades_ptr;
        counter--;
    }
};

This code will create a different counter for every template specialization. How do I make the counter global, meaning it will be incremented each time I create an object? In the Main, I created 3 Student_Grades objects, one with int specialization. one with double and one with char. The counter gives me 1. How do I get it to give me 3?

Upvotes: 3

Views: 185

Answers (1)

skypjack
skypjack

Reputation: 50548

You can use a base class the aim of which is to count the number of instances:

#include<cassert>

struct B {
    B() { cnt++; }
    virtual ~B() { cnt--; }
    static int cnt;
};

int B::cnt = 0;

template<typename T>
struct D: B {
    D(): B{} { }
};

int main() {
    D<int> d1;
    D<float> d2;
    assert(B::cnt == 2);
}

This way, it doesn't depend on the type of the specialization.

A slightly more configurable solution would be this one:

#include<cassert>

struct C {
    C() { cnt++; }
    virtual ~C() { cnt--; }
    static int cnt;
};

int C::cnt = 0;

template<typename T, class Counter = C>
struct D: Counter { };

int main() {
    D<int> d1;
    D<float> d2;
    assert(C::cnt == 2);
}

This one if you don't want to rely on inheritance:

#include<cassert>

struct C {
    C() { cnt++; }
    ~C() { cnt--; }
    static int cnt;
};

int C::cnt = 0;

template<typename T, class Counter = C>
struct D { const Counter c; };

int main() {
    D<int> d1;
    D<float> d2;
    assert(C::cnt == 2);
}

And so on...

Upvotes: 2

Related Questions