본문 바로가기
C++ STL/Part 01 C++ 문법

4장 템플릿

by 노오오오오옹 2021. 6. 22.

4-1. 함수 템플릿

여러 자료형의 함수를 하나의 함수로 만들어내는 틀이다.

template <typename T>
T Adder(T a, T b)
{
    return a+b;
}

int main()
{
    Adder(1, 2); // Adder<int>(1, 2) 인스턴스 생성
    Adder<int>(1, 2); // 명시적 지정
    
    Adder(2.3, 3.5); // Adder<double>(2.3, 3.5) 인스턴스 생성
    Adder<double>(2.3, 3.5); // 명시적 지정
}

매개변수를 가지는 함수 템플릿도 있다.

template <typename T, int size>
void PrintArray(T* arr)
{
	for(int i=0; i<size; ++i)
    {
    	cout << i << ": " << arr[i] << endl;
    }
}

int main()
{
    int arr[5] = {1,2,3,4,5};
    
    PrintArray<int, 5>(arr);
}

템플릿 특수화를 통해 상황에 따라 다른 구현을 할 수 있다.

class Point
{
    int x;
    int y;
    
public:
    explicit Point(int a, int b) : x(a), y(b) {}
    
    void print() { cout << p.x << ',' << p.y << endl; }
};

template<typename T>
void Print(T a)
{
    cout << a << endl;
}

template<> // cout << pt; 에 해당하는 함수 템플릿을 만들어준다. 
void Print(Point p)
{
    p.Print();
}

int main()
{
    int n = 10;
    double d = 2.3;
    Point pt(2,3);
    
    Print(n); // 10
    Print(d); // 2.3
    Print(pt); // 2,3
}

 

4-2. 클래스 템플릿

여러 클래스를 만들어내는 틀로, 아래는 T 타입의 배열 클래스이다.

template <typename T=int, int tCap = 100> // 디폴트: int, cap=100
class Array
{
    T* buf;
    int size;
    int capacity;
    
public:
    Array(int cap = tCap) : buf(0), size(0), capacity(cap)
    {
        buf = new T[capacity];
    }
    
    ~Array() { delete[] buf; }
    
    void Add(T num)
    {
        buf[size++] = num;
    }
    
    T operator[](int idx) const
    {
        return buf[idx];
    }
};

/*
// 아래는 클래스 템플릿 특수화 예시
template<>
class Array<float>
{
    float* buf;
    
    // 기존과 동일
};

*/

int main()
{
    Array<int> a1; // Array<int>
    Array<double> a2; // Array<double>
        
    a1.Add(1);
    a1.Add(2);
    a1.Add(3);
    
    Array<> a3; // int, 100 생성
    Array<double> a3; // double, 100 생성
}
  • 일반화 : template<typename T> class AAA
  • 특수화 : template<> class AAA<int>

 

4-3. STL을 위한 템플릿 예제

// 함수 템플릿
template <typename IterT, typename FuncT>
void For_each(IterT begin, IterT end, FuncT pf) // For_each(int* begin, int* end, void(*pf)(int)
{
    while(begin != end)
    {
        pf(*begin++);
    }
}

// 일반적인 함수
void PrintInt(int data)
{
    cout << data << ' '; 
}

// 함수 탬플릿
template<typename T>
void PrintT(T data)
{
    cout << data << ' ';
}

// 템플릿 클래스
template<typename T>
struct PrintClass
{
    string seq;
    
    explicit PrintClass(const string& s = " ") : seq(s) { }
    
    void operator()(T data) const
    {
    	cout << data << ' '; 
    }
};

int main()
{
    int arr[5] = {1,2,3,4,5};
    
    For_each(arr, arr+5, PrintInt); 
    // int 타입이 정해져 있기 때문에 명시안해도된다.
    // For_each<int*, void(*pf)(int)>() 생성
    
    For_each(arr, arr+5, PrintT<int>); 
    // PrintT를 호출하기 때문에, 타입을 명시해야한다.
    
    string srr[3] = {"a", "ab", "abc"};
    For_each(srr, srr+3, PrintClass<string>());
}

 

'C++ STL > Part 01 C++ 문법' 카테고리의 다른 글

3장 함수 객체  (0) 2021.06.22
2장 함수 포인터  (0) 2021.06.17
1장 연산자 오버로딩  (0) 2021.06.17

댓글