씹어먹는 C++ 11일차
❗참고 : https://modoocode.com/219
C++ Template
- 개발자가 원하는 타입을 넣어주면 알아서 코드를 찍어내는 틀
- generic programming
- 일반적인 코드를 작성하고, 이 코드를 정수나 문자열과 같은 여러 타입에 대하여 재사용 하는 기법
Class template 정의
template <typename T>
class class이름 {
// template name T를 데이터 타입으로 사용 가능
}
Function template
template <typename T>
T functionName(T x, T y) {
// 함수 구현
}
Class Template 사용
- 정의된 템플릿을 사용하는 방법
- class template instantiation (템플릿 인스턴스화)
- class template에 인자를 전달해서 실제 코드를 생성함
class이름<type> typeName; // T에 type이 전달됨
class이름<int> intName; // T에 int가 전달됨
class이름<std::string> stringName; // T에 std::string이 전달됨
Class Template specialization
- 다른 매개변수 사용 등의 특수한 상황에 대해 따로 처리하는 경우
template<> // 전달하는 템플릿 인자가 없더라도 특수화하고 싶은 경우
활용 예시,
template <typename A, typename B, typename C> // class template 정의
class test {};
- A가 int고, C가 double인 경우에 대해 따로 처리하고 싶을 때,
- A와 C에 대해서는 fix 시키고, B에 대해서는 template 적용
template <typename B>
class test<int, B, double> {};
- B 도 특수화 하고 싶은 경우,
template <>
class test<int, int, double> {};
Function Template 사용
#include <iostream>
#include <string>
template <typename T>
T test(T& a, T& b) {
return a > b ? a : b;
}
int main() {
int a = 1, b = 2;
std::cout << test(a, b) << std::endl;
std::string s = "test", t = "programming";
std::cout << test(s, t) << std::endl;
return 0;
}
- Func test도 인스턴스화 전에는 compile time에 코드로 변환되지 않음
- test(a, b)가 호출되는 부분에서 인스턴스화 됨
- test
(a, b) 또는 test (s, t)와 같은 형태로 컴파일러가 알아서 변환해 사용함
- test
template의 활용
Functor
- 함수 객체 (Fuction Object)
- 함수는 아니지만 함수인척 하는 객체
타입이 아닌 템플릿 인자 (non-type template arguments)
#include <iostream>
template <typename T, int num>
T add_num(T t) {
return t + num;
}
int main() {
int x = 3;
std::cout << add_num<int, 5>(x) << std::endl;
return 0;
}
실행 결과
8
- 코드 설명
- template의 인자로 T를 받고, 추가로 함수의 인자처럼 int num을 추가로 받음
- 해당 템플릿 인자는 add_num 함수를 호출 시, <> 을 통해 전달함
- 템플릿 인자로 전달할 수 있는 type
- 정수 (bool, char, int, long)
- 포인터
- enum
- std::nullptr_t (null pointer)
- float과 double은 제외됨 (C++20 에서 변경됨)
Default template arguments
template <typename T, default args (type name = default value)>
template <typename T, int num = 5>
T add_num(T t) {
return t + num;
}
int main() {
int x = 3;
std::cout << add_num(x) << std::endl;
return 0;
}
가변 길이 template
template <typename T, typename... Types>
- template parameter pack
- typename 뒤에 … 를 의미
- 0개 이상의 템플릿 인자를 나타냄
- 처음 T 외에 나머지 인자들은 전부 Types가 나타냄
- example
template <typename T, typename... Types>
void print(T arg, Types... args) {
std::cout << arg << ", ";
print(args...);
}