본문 바로가기
💻 programming/c++

[c++] template

by 연구원-A 2020. 12. 15.
반응형

Template

Templates in C++ - GeeksforGeeks

c++에서 템플릿은 매우 간단하면서도 강력한 기능을 제공합니다. 템플릿은 데이터 타입만 다른 똑같은 함수를 여러 번 작성하지 말고, 데이터 타입을 인자로 전달하자는 단순한 아이디어에서 출발했습니다. 예를 들어 서로 다른 데이터 타입 (정수, 실수, 문자 등)을 정렬하는 sort() 함수를 구현해야 한다고 생각해봅시다. 이 때 템플릿을 이용하면 하나의 소스 코드로 각기 다른 데이터 타입에 따른 동작을 정의할 수 있습니다.

템플릿의 동작

템플릿은 마치 매크로처럼 컴파일 시간에 확장 (expansion)됩니다. 매크로와 다른 점은 컴파일러가 템플릿을 확장하기 전에 타입 체크 (type cheking)을 수행한다는 점입니다. 소스 코드는 function/class 만 가지고 있지만, 컴파일된 코드는 사용된 데이터 타입만큼 같은 소스 코드를 여러번 복사해서 가지고 있게 됩니다.

템플릿의 종류

  • 함수 템플릿 (function template)
  • 클래스 템플릿 (class template)
  • 변수 템플릿 (variable template) ; c++14

함수 템플릿 (function template)

템플릿을 이용하면 다른 데이터 타입에 대한 제네릭 함수 (generic function)을 만들 수 있습니다. c++ STL 알고리즘에 포함된 sort, max, min 등이 함수 템플릿의 사용 사례에 해당합니다.

#include <iostream> 
using namespace std; 

// One function works for all data types.  This would work 
// even for user defined types if operator '>' is overloaded 
template <typename T> 
T myMax(T x, T y) 
{ 
   return (x > y)? x: y; 
} 

int main() 
{ 
  cout << myMax<int>(3, 7) << endl;  // Call myMax for int 
  cout << myMax<double>(3.0, 7.0) << endl; // call myMax for double 
  cout << myMax<char>('g', 'e') << endl;   // call myMax for char 

  return 0; 
}

클래스 템플릿 (class template)

함수 템플릿과 마찬가지로 클래스 템플릿은 데이터 타입과 독립적인 클래스를 정의할 때 사용할 수 있습니다. 특히 Array, Queue, Stack같은 컨테이너를 만들 때 특히 유용합니다.

#include <iostream> 
using namespace std; 

template <typename T> 
class Array { 
private: 
    T *ptr; 
    int size; 
public: 
    Array(T arr[], int s); 
    void print(); 
}; 

template <typename T> 
Array<T>::Array(T arr[], int s) { 
    ptr = new T[s]; 
    size = s; 
    for(int i = 0; i < size; i++) 
        ptr[i] = arr[i]; 
} 

template <typename T> 
void Array<T>::print() { 
    for (int i = 0; i < size; i++) 
        cout<<" "<<*(ptr + i); 
    cout<<endl; 
} 

int main() { 
    int arr[5] = {1, 2, 3, 4, 5}; 
    Array<int> a(arr, 5); 
    a.print(); 
    return 0; 
}

변수 템플릿 (variable template)

2020/12/15 - [c++ language/basics] - [c++] variadic template (가변 길이 템플릿)

More

템플릿에 하나 이상의 인자를 사용하기

#inlcude <iostream>
using namespace std;

template<class T, class U>
class A {
    T x;
    U y;
 public:
    A() { cout << "Construct Called" << endl; }
};

int main() {
    A<char, char> a;
    B<int, double> b;
    return 0;
}

템플릿 인자에 기본값 할당하기

#include <iostream>
using namespace std;

template <class T, class U = char>
class A {
    T x;
    U y;
    A() { cout << "Constructor Called" << endl; }
};

int main() {
    A<char> a; // This will call A<char, char>
    return 0;
}

템플릿 특수화 (template specialization)

2020/12/15 - [c++ language/basics] - [c++] template specialization

템플릿에 비형식 파라미터 (non-type) 전달하기

템플릿의 인자로 데이터 타입을 전달하는 것 외에도 값을 전달할 수 있습니다. 이러한 비형식 파라미터는 주로 템플릿 인스턴스에서 사용하는 최대, 최소 값과 같은 상수로 이용됩니다. 중요한 것은 이러한 비형식 파라미터는 모두 상수여야 한다는 것입니다. 템플릿은 컴파일 시간에 인스턴스화 되기 때문입니다. 아래 예제 코드에서 10000이나 25를 같은 값을 가진 변수로 치환하면, 컴파일에러가 발생하는 것을 확인할 수 있습니다.

// A C++ program to demonstrate working of non-type 
// parameters to templates in C++. 
#include <iostream> 
using namespace std; 

template <class T, int max> 
int arrMin(T arr[], int n) 
{ 
   int m = max; 
   for (int i = 0; i < n; i++) 
      if (arr[i] < m) 
         m = arr[i]; 

   return m; 
} 

int main() 
{ 
   int arr1[]  = {10, 20, 15, 12}; 
   int n1 = sizeof(arr1)/sizeof(arr1[0]); 

   char arr2[] = {1, 2, 3}; 
   int n2 = sizeof(arr2)/sizeof(arr2[0]); 

   // Second template parameter to arrMin must be a constant 
   cout << arrMin<int, 10000>(arr1, n1) << endl; 
   cout << arrMin<char, 256>(arr2, n2); 
   return 0; 
}
반응형

'💻 programming > c++' 카테고리의 다른 글

[c++] functor (function object)  (0) 2020.12.15
[c++] template specialization  (0) 2020.12.15
[c++] any  (0) 2020.12.15
[c++] optional  (0) 2020.12.15
[c++] move  (0) 2020.12.15

댓글