템플릿 기초 1, 2

CJB_ny·2022년 8월 23일
0

C++ 정리

목록 보기
64/95
post-thumbnail

템플릿

템플릿 내용이 방대해서 이거 하나로만으로도 책을 낼 수 있다.

함수나 클래스를 찍어내는 툴

함수 템플릿

이런식으로 함수 오버로딩을 통해서 다른 인자타입을 받는것을 늘릴 수 있다.

Print("Hello");

여기의 '조커 카드'가 '템플릿'이다.

이 함수들을 보면 각각의 타입으로 만들어 진 것을 볼 수 있다.

T라는 타입에 따라 다양한 함수의 버젼이 만들어진다고 보면 된다.

int를 받는 함수를 하나라도 사용을 하는 순간 컴파일러가 int를 받는 Print 함수를 만들어 내는 것이다.

이런 각기 다른 버젼들이 컴파일 단계에서 생성이 된다.

컴파일러가 추론을 해서 만들어 주는 것이다.

그래서 이런식으로 명시적으로 int를 적어줄 수 있는데

50.0f과 같은 float를 넣어주어도 int형을 호출하게된다.

선호도 차이

여기다가 typename이라고 넣어주어도되고

class라고 넣어 주어도 상관없다. -> 선호도 차이.

활용

T를 한번만 사용해야 하는거 아님!

인자를 다르게 넣는 경우?

각기 다르게 인자를 넣어주게 될 경우는..??

템플릿은 하나의 인자만 사용하는게 아니다.

이와같은 케이스를 커버하기 위해서

T1, T2라는 인자가 동일해야한다는 강제사항 넣지를 않았다.

템플릿 특수화

커스텀 클래스 등장할 경우

지금 Knight라는 클래스가 있을 경우

Knight k1;

Print(k1); 

인자로 넘겨주는 부분이 문법적인 오류는 아니다.

다만 template < typename T > Print(T a) { cout << a << endl; }

함수 안에서 '<<'라는 연산자를 수행해야 하는데

Knight에 '<<'라는 연산자가 없기 때문에 빌드가 통과되지 못한다.

우리가 커스텀한 클래스에다가 '<<'연산자를 수행하는데

컴파일러가 우리가 커스텀한 클래스가 뭔지 알고 '<<'연산자를 지원을 하나??

방법

Knight라는 클래스 내에서 '<<' operator 를 오버로딩 해줄 수도 있고

아니면

이렇게 cout '<<' 자체를 오버로딩 해줄 수 있다.

그런데 Knight만들 특별하게 취급하고 싶을 경우

그럴떄 사용하는 것이 '템플릿 특수화'이다.

템플릿 특수화

규칙을 이렇게 만들어주었지만 예외적인 사항이 있을 경우

사용하는것이 템플릿 특수화 이다.

Knight 에 대해서는 특수한 처리를 해주겠다.

다른 int, float, double, const char* 와 같은 경우는

위에버젼을 따르고 Knight의 경우에만 아래버젼을 따른다.

클래스 템플릿

int형, float형 double형 만들고싶으면

함수 템플릿과 거의 비슷하게

이렇게 해주면된다.

typename 무적권 필요?한것은 아님 ❗

지금

template <typename T, int SIZE>
class RandomBox {};

이렇게 들어갔는데

template < > 이 안에 들어가는 것은 '골라줘야 하는 목록' 이라고 볼 수 있다.

RandomBox<int, 20> rb1;

이렇게 만들어 줄 수 있다는 것이다.

그러면 rb1의 멤버 배열의 크기는 20으로 만들어짐.

그리고 RamdomBox< int > 버젼과 RandomBox< float > 가 완전히 다른 클래스로 인식이 되는 것처럼.

RandomBox< int, 10> 버젼과 RandomBox<int, 20> 버전도 완전히 다른 클래스로 인식이 된다.

각기 완전히 독립적인 클래스로 따로따로 만들어 진다.

이런식으로 복사대입 연산자를 수행할려고해도

두 타입이 일치하지 않아서 컴파일 오류뜬다.

(물론 operator = 를 오버로딩 하면 되겠지)

템플릿 특수화 (클래스)

현재 T가 double인 경우에서만 특수화를 한다고 해보자.

그러면 위에서 이렇게만 해주면 에러가 나고
이게 아니라

이렇게 적어주어야한다.

이렇게 해주면 아름답게 동작을 한다.

profile
https://cjbworld.tistory.com/ <- 이사중

0개의 댓글