[C++] 템플릿(Template) 프로그래밍
카테고리: Cpp
이 글은 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개 만들자
참조
💻 열심히 공부해서 작성 중이니 오류나 틀린 부분이 있을 경우
언제든지 댓글 혹은 메일로 알려주시면 감사하겠습니다! 😸
댓글 남기기