본문 바로가기

C++ Programming/STL

템플릿이란? (Template)

1. 템플릿은 하나 또는 그 이상의 정해지지 않은 임의의 데이터 타입을 위해서 작성된 함수 또는 클래스이다.

template <class T>
inline const T& max(const T& a,const T& b)
{
      return a < b ? b:a;
}

첫째줄에 정의된 T는 호출자가 함수를 호출할때 지정하여 넘겨주는 임의의 데이터 타입이다.
class 키워드는 어떤 타입을 값으로 받아들이는 변수의 이름역할을 한다.
class 대신 typename이라는 새로운 키워드를 사용할 수 있다.

템플릿을 쉽게 사용하기 위한 방법은 헤더 파일에 인라인 함수로 구현하는 것이다.

그리고 해당 cpp파일에

export template <class T>T min(const T& a, const T& b)
{
}

or

template <class T>T min(const T& a,const T&b); //선언
int main ()
{
    int j=0;k=1;
    int smaller = min(j,k);
    return 0;
}

처럼 쓸수 있다.

2. 비타입(NONTYPE) 템플릿 파라미터 

   bitset<32> flags32; //32비트의 bitset
   bitset<50> flags50; //50비트의 bitset
   서로 다른 타입이다. 서로 비교불가 할당불가

3. 디폴트 템플릿 파라미터 
 
   template<class T, class container = vector<T>>
   class MyClass;

   한개의 인자만 넘겨주었을경우 두 번째 인자는 디폴트 인자를 사용한다. 
   MyClass<int> x1;//MyClass<int,vector<int>>와 동일함

4. typename 키워드
   -  다음에 따라오는 식별자가 타입이라는 것을 명시하기 위해 사용된다. 
   template <class T>
   class MyClass {
        typename T::SubType *ptr; //SubType이 class T의 타입이라는 사실을 명확히 하기 위해서 사용되었다.
        ..
    }
        typename이 없다면 타입T의 SubType의 값과 ptr을 곱한 결과가 된다. 

    C++에서의 일반적인 규칙은 typename으로 제한된 경우를 제외하고는 템플릿의 어떤 식별자도 값으로 간주한다.
    typename은 템플릿 선언부에서 class를 대신해 사용할 수도 있다. 
    Template <typename T> class MyClass;

  5. 멤버 템플릿
      class MyClass{
          ...
          template <class T>
          void f(T);
       };
       MyClass::f는 어떠한 타입도 인자로 받을 수 있는 멤버함수 

       template <class T>
       class MyClass {
              private:
                   T value;
              public:
                   void assign(const MyClass<T>& x){ //x는 this와 같은 타입
                          value = x.value;
                   }   
                    ...
        };

        void f()
        {
              MyClass <double> d;
              MyClass <int> i;
              d.assign(d); //OK
              d.assign(i); //에러 double로 이미 타입이 정해져있다. 
         }

           -> template <class X>
                void assign(const MyClass<X>& x){ //다른 템플릿 타입을 허용한다. 에러제거
                         value = x.getValue();
                }
  
6. 기본적인 타입을 위한 명시적인 초기화

     int i1; //정의되지 않은값
     int i2 = int (); //0으로 초기화
     T x = T(); //T가 기본적인 타입의 경우 0으로 초기화하는 것을 보장

7. 예외처리 

   void f() throw(bad_alloc); //f()는 bad_alloc예외만 던질것이다.
   void f() throw(); //f()는 예외를 던지지 않는다. 
   알수없는 예외는 bad_exception을 발생