[C++] 템플릿(Template) 프로그래밍

Date:     Updated:

카테고리:

태그:

이 글은 C++ 템플릿(Template) 프로그래밍을 공부하고 정리한 글입니다

템플릿(Template)

  • Java와 C#에서의 제네릭(generic) 메서드/클래스와 비슷
  • STL 컨테이너 또한 템플릿
  • 코드를 자료형마다 중복으로 작성하지 않아도 됨

    함수 템플릿

    • 함수 템플릿을 호출할 때 템플릿 매개변수를 생략할 수 있음

    템플릿 작동 방식

    • 템플릿을 인스턴스화할 때마다 컴파일러가 내부적으로 코드를 생성
      • 템플릿에 넣는 자료형 가짓수에 비례해서 exe 파일 크기 증가
    • 컴파일 타임에 어느 정도 다형성을 부여할 수 있음

      코드 예시

      // MyMath.h
      template <typename T> // 또는 template <class T>
      T Add(T a, T b)
      {
          return a + b;
      }
        
      // Main.cpp
      #include "MyMath.h"
        
      int main()
      {
          std::cout << Add<int>(3, 10) << std::endl;
          std::cout << Add<float>(3.14f, 10.14f) << std::endl;
        
          return 0;
      }
      

    typename vs class

    • 차이는 없다

    클래스 템플릿

    • 개체를 선언할 때 템플릿 매개변수를 명시해야 한다
    • 구현부를 헤더 파일에 구현해야 링크 에러가 안 생긴다

      코드 예시

      // MyArray.h
      template<typename T>
      class MyArray
      {
      public :
          bool Add(T data);
          MyArray();
      
      private :
          enum { MAX = 3 };
          int mSize;
          T mArray[MAX];
      };
      
      template<typename T>
      inline bool MyArray<T>::Add(T data)
      {
          return false;
      }
      
      template<typename T>
      MyArray<T>::MyArray()
          : mSize(0)
      {
      }
      
      // main.cpp
      MyArray<int> scores;    // OK
      MyArray scores;         // 에러
      

    두 개의 템픞릿 매개변수

    template<typename T, typename U>
    void Print(const T& a, const U& b)
    {
        std::cout << a << " / " << b << std::endl;
    }
    
    template<typename T, typename U>
    class MyClass
    {
    private:
        T mX;
        U mY;
    };
    

    템플릿 특수화(Specialization)

    • 특정한 템플릿 매개변수를 받도록 템플릿 코드를 커스터마이즈할 수 있음

      전체 템플릿 특수화

      • 템플릿 매개변수 리스트가 비어 있음
      template<typename VAL, typename EXP>
      VAL Power(const VAL value, EXP exponent) {}   // 모든 형을 받는 제네릭 power()
        
      template <>
      float Power(float value, float exp)           // float을 받도록 특수화된 power()
      

      부분 템플릿 특수화

      template<typename T, typename Allocator>
      class std::vector<T, Allocator> {}          // 모든 형을 받는 제네릭 vector
        
      template<typename Allocator>
      class std::vector<bool, Allocator> {}       // bool을 받도록 특수화된 vector
      

    장점과 단점

    • 컴파일러가 컴파일 도중에 각 템플릿 인스턴스에 대한 코드를 만들어줌
      • 컴파일 타임은 비교적 느림
      • 템플릿 매개변수를 추가할수록 더 느려짐
      • 하지만 런타임속도는 더 빠를지도 모름
      • 실행 파일 크기가 커지기 때문에 항상 그런 것은 아님
    • 컴파일 도중에 다형성을 부여할 수 있음
      • C++ 프로그래머가 너무 많이 잘못 썻던 기능
      • 가상 테이블이 없어서 프로그램이 더 빠름
      • 하지만 exe 파일이 커지면 느려질 수 있음
      • 코드 읽기가 더 힘듦

    템플릿 프로그래밍 베스트 프랙티스

    • 컨테이너이 경우 매우 적합
      • 아주 다양한 형들을 저장할 수 있음
    • 컨테이너가 아닌 경우
      • 각기 다른 서넛 이상의 자료형을 다룬다면 템플릿을 쓰자
      • 두 가지 정도라면 그냥 클래스 2개 만들자


참조

포큐아카데미 C++ 언매니지드 프로그래밍



💻 열심히 공부해서 작성 중이니 오류나 틀린 부분이 있을 경우 
  언제든지 댓글 혹은 메일로 알려주시면 감사하겠습니다! 😸

맨 위로 이동하기

Cpp 카테고리 내 다른 글 보러가기

댓글 남기기