2. C++ template
공텍쥐페리와 어린 기획자
공텍쥐페리는 비행을 하다가 어떤 프로젝트에 불시착했어요. 거기에서 만난 어린 기
획자는 그에게 말했습니다 “큰 숫자를 리턴하는 함수 하나만 만들어 줘…”
공텍쥐페리는 어린 기획자에게 int를 인자로 받는 함수를 만들어 주었어요. 그러자 어
린 기획자는 함수를 내던지며 “아냐, 내가 원하는 자료형은 이런 게 아냐. 소수점 이
하 숫자를 비교할 수 없잖아"라고 말했어요.
그래서 공텍쥐페리는 float를 인자로 받는 함수를 만들어 주었어요. 그런데 어린 기획
자는 또 투정을 부리며 “난 글자도 비교하고 싶어, 이딴 자료형은 필요 없어!”
화가 난 공텍쥐페리는 아무렇게나 상자 하나를 그려놓고 이렇게 말했어요 “이 상자
안에 네가 원하는 자료형이 있어“
그러자 어린 기획자는 밝은 미소를 지으며 함수를 가지고 떠났답니다.
3. C++ template
공텍쥐페리와 어린 기획자
함수를 만들 때, 다양한 자료형을 인자
로 받아야 하는 경우
각각 다른 자료형의 데이터를 인자로
받는 함수를 일일히 ctrl+c ,ctrl+v 해야
할까?
좀 더 똑똑하게 코딩할 수는 없을까?
왜 없겠습니까! 있지요!
4. Template function
템플릿
여러 다른 자료형을 템플릿 인자로 받아 함수, 클래스, 구조체 내부
에서 활용할 수 있도록 한 것
template <typename Type> <-함수 템플릿
Type max(Type a, Type b){ …} <-템플릿 함수
컴파일 과정 중 해당 함수가 어떤 자료형으로 호출될 지 결정되어
실제 자료형으로 함수가 생성된다.
단, 하나의 typename은 하나의 자료형으로만 취급된다.
7. Template class
템플릿 클래스
템플릿을 사용한 클래스(간단)
template <typename T> class Stack{…}; <-선언시
Stack<int> myStack; <-사용시
템플릿 함수와 달리 컴파일러가 인자를 추론해주지 않음, 클래스 사
용 시 명시적으로 인스턴스화 해주어야 한다
8. Example #3
일반적인 방식으로 클래스 함수의 선언과 정의를
분리할 경우 컴파일 되지 않는다.
*.inl(inline) 파일에 함수를 정의하고 헤더 파일에서
포함해줘야 함!
Stack.h
Stack.inl
9. Supplement
주의할 점
함수 템플릿과 템플릿 함수(클래스)는 한 몸!
함수의 선언과 정의를 분리할 경우 함수 선언시에 template도 함께 선
언해야 함
class, typename 둘 다 사용 가능하지만 좀 더 의미가 명확한 typename
을 사용하는 것이 좋다
컴파일 시점에서 코드를 생성하기 때문에 당연하게도 남발하면 컴파
일 시간이 길어진다
10. Template metaprogramming
논 타입 템플릿
템플릿 인자로 자료형이 아닌 non-type 파라미터를 지정할 수 있다.
템플릿 함수 내부에서 상수처럼 사용된다
template <int N> int factorial(){…}; <- 선언
factorial<10>(); <- 상수만 입력 가능
Template metaprogramming
컴파일 시점에 코드를 생성하는 template의 특성을 이용해 복잡한
계산을 필요로 하는 함수를 컴파일 시점에 계산하도록 하여 실행시
간을 보다 빠르게 하는 프로그래밍 기법
11. Example #4
일반적인 재귀함수로 구현할 경우 런타임
시점에 계산됨
템플릿 메타프로그래밍 기법 사용시 컴파
일 시점에 계산되어 런타임 시점에서는
상수처럼 사용됨
12. Supplement
Non-type 파라미터는 정수, 상수형 값(열거형 포함), 외부 링크를 가진
객체에 대한 포인터만 사용 가능하다
응? 또 뭔가 쓸 게 있었는데 콜라 사오는 동안 까먹었다
13. Standard template library
STL
C++ 템플릿을 사용해 만든 표준 라이브러리
일반적인 자료 구조 컨테이너와 알고리즘이 구현되어 있음
vector, deque, list, map, set, stack, queue
bitset, algorithm, functional, iterator
자료구조에 대해서는
14. 컨테이너
기본적인 사용법
vector, deque, list, stack, queue <- 시퀸스 컨테이너
Map, hash_map set <- 연관 컨테이너
std::vector<int> myVector;
std::map<double,int> myMap;
컨테이너별로 사용 가능한 멤버가 다름, 검색하면 나옴
15. Itorator
Itorator
컨테이너 내부의 요소를 순회하는 방법을 캡슐화한 객체
컨테이너의 포인터라고 생각하면 됨
증감 연산자와 비교 연산자, * ->연산자 사용 가능
list<int>::iterator myIter;
Iterator – 순방향으로 순회
const_iterator – 읽기 전용으로 순회
reverse_iterator – 역방향으로 순회
const_reverse_iterator – 읽기 전용 역방향으로 순회
16. Algorithm
어디 쓰는 물건인가요?
템플릿 함수로 구현된 알고리즘 라이브러리
STL 컨테이너 뿐만 아닌 일반 배열 구조도 사용 가능
변경 불가 시퀀스 알고리즘 (find, for_each …)
변경 가능 시퀀스 알고리즘 (generate, copy, remove, replace …)
정렬 관련 알고리즘 (sort, binary_search, merge)
범용 수치 알고리즘 (accumulate, inner_product)
예를 들어 위의 예제 함수에서 a에 int를 대입하고, b는 double를 대입하는 경우 컴파일러가 인자를 추론하는 데 실패한다. 이런 경우 template 파라메터 목록을 수정하거나 명시적으로 인스턴스화하면 해결됨
함수 템플릿 – 함수 선언을 위한 템플릿
템플릿 함수 – 템플릿을 사용한 함수
다른 타입이 인자로 들어가는 경우 리턴값을 잘 체크해야 함
Non-type parameter에 Default 값을 지정해줄 수도 있음
읽기는 좀 힘듬
시퀸스 컨테이너 – 순서대로 자료를 보관
연관 컨테이너 – 어떠한 key와 짝을 이루어 자료를 보관
Find – 컨테이너에 있는 데이터중 원하는 것을 찾음
For_each – 컨테이너에 담긴 데이터를 파라미터로 넘겨 함수를 실행시킴
Binary_serach – 정렬된 컨테이너에서 특정 데이터가 지정 구간에 있는지 조사, 반드시 sort가 선행
Merge – 두 개의 정렬된 구간을 합침, 반드시 sort 선행
Accumulate – sum
Inner_product – 두 시퀀스의 내적을 계산