'템플릿(template)'은 타입을 추상화하는 방법입니다. 타입을 추상화한다는게 무슨 말일까요?

아래 예제는 정수 값을 담을 'Array 컨테이너'입니다.

class Array {
private:
    int* buf;
    int size;      // 원소의 개수
    int capacity;  // 저장 가능한 메모리 크기
    
public:
    explicit Array(int cap = 256) : buf{ nullptr }, size{ 0 }, capacity{ cap } {
        buf = new int[capacity];
    }
    
    ~Array() { delete[] buf; }
    
    void Add(int data) { 
        if (size < capacity)
            buf[size++] = data;
    }
    
    int operator[](int index) const {
        return buf[index];
    }
    
    int GetSize() const {
        return size;
    }
};

void main() {
    Array arr;
    
    arr.Add(10);
    arr.Add(20);
    arr.Add(30);
    
    for (int i = 0; i < arr.GetSize(); ++i)
        cout << arr[i] << endl;
}

정수 값을 담을수 있는 'Array 컨테이너'를 만들었습니다. 그런데 정수가 아닌 실수를 담고 싶다면 어떻게 해야할까요?

간단하게 위의 예제에서 생성자 부분에 있는 'new int[capacity]를 new double[capacity]'로 바꿔서 클래스를 새로 정의하는 방법이 있습니다. 하지만 그러기엔 아무래도 찝찝합니다. 코드의 중복이 생길 뿐더러, 유연하지도 못합니다. 이때, '템플릿(template)'을 사용하면 아주 매끄럽고 유연하게 해결할 수 있습니다.

 

'템플릿(template)'을 적용시킨 'Array 컨테이너'입니다.

template<typename T>
class Array {
private:
    int* buf;
    int size;      // 원소의 개수
    int capacity;  // 저장 가능한 메모리 크기
    
public:
    explicit Array(int cap = 256) : buf{ nullptr }, size{ 0 }, capacity{ cap } {
        buf = new T[capacity];
    }
    
    ~Array() { delete[] buf; }
    
    void Add(int data) { 
        if (size < capacity)
            buf[size++] = data;
    }
    
    int operator[](int index) const {
        return buf[index];
    }
    
    int GetSize() const {
        return size;
    }
};

void main() {
    Array<int> arrInt;
    arrInt.Add(10);
    arrInt.Add(20);
    arrInt.Add(30);
    
    for (int i = 0; i < arrInt.GetSize(); ++i)
        cout << arrInt[i] << endl;
        
    Array<double> arrDouble;
    arrDouble.Add(1.1);
    arrDouble.Add(2.2);
    arrDouble.Add(3.3);
    
    for (int i = 0; i < arrDouble.GetSize(); ++i)
        cout << arrDouble[i] << endl;
}