Lasiyan
Code

C++ Template 기본 개념

#C++#템플릿#제네릭
  1. 템플릿 (Template)
    – 무언가를 찍어내는 틀
    – 함수 템플릿, 클래스 템플릿, …
    – 함수를 찍어내는 틀, 클래스를 찍어내는 틀, …

  2. 함수 템플릿 (Function Template)
    예를들어 두 수를 바꾸는 Swap 함수를 구현할 때

#include <iostream>
using namespace std;
void Swap(int &n1,int &n2) {
    int temp = n1;
    n1 = n2;
    n2 = temp;
}
void main() {
    int n1 = 10, n2 = 40;
    cout << "before n1 : " << n1 << ", n2 : " << n2 << endl;
    Swap(n1, n2);
    cout << "after  n1 : " << n1 << ", n2 : " << n2 << endl;
}

를 사용 할 경우 int 형에 한하여 문제 없이 Swap을 사용할 수 있다.

그러나 다른 자료형에 대하여 Swap이 필요할 경우 템플릿을 사용하지 않으면

#include <iostream>
using namespace std;
//template<typename T>
void Swap(int &n1,int &n2) {
    int temp = n1;
    n1 = n2;
    n2 = temp;
}
void Swap(double &n3, double &n4) {
    double temp = n3;
    n3 = n4;
    n4 = temp;
}
void main() {
    int n1 = 10, n2 = 40;
    cout << "before n1 : " << n1 << ", n2 : " << n2 << endl;
    Swap(n1, n2);
    cout << "after  n1 : " << n1 << ", n2 : " << n2 << endl;
    double n3 = 1.11, n4 = 9.99;
    cout << "before n3 : " << n3 << ", n4 : " << n4 << endl;
    Swap(n3, n4);
    cout << "after  n3 : " << n3 << ", n4 : " << n4 << endl;
}

와 같이 함수를 오버로딩 하여 중복되게 사용해야 한다. 이는 자료형이 많아질 수 록 코드가 복잡해지며 가독성이 떨어지기 때문에 위와 같은 문제 해결을 위하여
템플릿을 사용한다.

ex.

#include <iostream>
using namespace std;
template<typename T>
void Swap(T &n1,T &n2) {
    T temp = n1;
    n1 = n2;
    n2 = temp;
}
void main() {
    int n1 = 10, n2 = 40;
    cout << "before n1 : " << n1 << ", n2 : " << n2 << endl;
    Swap(n1, n2);
    cout << "after  n1 : " << n1 << ", n2 : " << n2 << endl;
    double n3 = 1.11, n4 = 9.99;
    cout << "before n3 : " << n3 << ", n4 : " << n4 << endl;
    Swap(n3, n4);
    cout << "after  n3 : " << n3 << ", n4 : " << n4 << endl;
}

먼저 template 로 템플릿을 정의하고 참조자를 활용하여 참조에 의한 호출을 수행한다. 위 방법은 컴파일러가 전달되는 인자의 자료형을 보고 T의 타입을 유추하는 것이며 Swap(n1, n2) 또는 Swap(n3, n4) 로 사용할 수 있다.

참고로 템플릿의 정의에서 T는 일반적으로 쓰이는 이름이며 typename을 class로 써도 상관없다.

  1. 클래스 템플릿 (Class Template)
    함수 템플릿과 동일하게 다양한 자료형을 가질 수 있는 클래스 마다 별도로 클래스 생성을 하는 것이 아니라 클래스 템플릿을 사용하여 다양한 자료형에 대한 클래스를 생성하는 “틀”을 사용한다.
#include <iostream>
using namespace std;
template<typename T>
class Data {
private:
    T data;
public:
    Data(T _data) : data(_data) { }
    void print() {
        cout << "data : " << data << endl;
    }
};
void main() {
    Data<int> d1(5);
    // Data<int> d1 = { 3 }; 와 동일
    d1.print();
    Data<char> d2('A');
    d2.print();
    Data<double> d3(3.14);
    d3.print();
}

단, 함수 템플릿의 경우 <자료형>을 생략할 수 있지만
클래스 템플릿에서는 반드시 <자료형>을 선언해야 한다.

참고 : http://blog.eairship.kr/178