본문 바로가기
언어/C++

(C++) 템플릿

by 흥부와놀자 2020. 9. 14.

템플릿은 함수나 클래스에서 실행 시 받는 타입별로 따로 구현해놓지 않아도 임의의 타입에 맞게 자동으로 구현되는 기능이다.

 

템플릿의 과정

컴파일이 시작되면 구체적 타입에 맞게 템플릿 인스턴스가 생성 된다. 이 과정은 단순 코드의 복사 붙여넣기와 동일하며 RunTime에 타입을 변화시켜주는 자바의 제네릭과는 확실히 다르다.  virtual 같은 동적 바인딩과도 다른것이다.

 

특수화 템플릿

특수화 템플릿은 특정한 타입만의 예외를 제공해주는 템플릿이다. 특수화 시 지켜야 할점이 있는데 매개변수와 리턴값의 타입을 똑같이 맞춰줘야 한다.   

template<class T>
void test(T data)
{
    std::cout << data << std::endl;
}

template<>
void test(const char* data)
{

    std::cout << "Stirng은" << std::endl;

    std::cout << data << std::endl;
}
int main()
{
    test(10);
    test("kamja");
}


실행결과
10 
Stirng은 
kamja

위의 코드에서 보듯 test()함수에 문자열이 들어올 때만 예외적으로 출력 해줌을 알 수 있다.

 

복수 타입 템플릿

여러 타입의 템플릿을 사용하려면 아래와 같이 사용하면 된다.

template<class T1, class T2>
void test(T1 data1, T2 data2)
{
    std::cout << data1 + data2 << std::endl;
}

int main()
{
    test(10,0.1f);
}

 

후행반환

그렇다면 위의 test함수에서 data1+data2한 값을 리턴시키려면 어떻게 해야할까?

T1과 T2의 타입에 따라서 정수가 나올수 있고 실수가 나올수 있다. 

 

이를 위해서는 auto 와 delctype 키워드를 알아야 한다. 

 

auto

auto키워드는 C++11 부터 시작된 문법으로써 초기값에 따라 타입추론 능력을 가진다. 물론 추론은 컴파일 타임에서 진행되며 함수의 매개변수 같은 곳은 컴파일러의 추론이 불가능하기에 사용할 수 없다.

 

decltype

해당 값의 구체적 타입을 알려주는 키워드이다. 역시 컴파일 타임에서 실행된다.

 

후행반환은 다음과 같이 이루어진다.

template<class T1, class T2>
auto test (T1 data1, T2 data2) -> decltype(data1+data2)
{
    return data1 + data2;
}

int main()
{
    auto a = test(10, 0.2f);
    std::cout<<a<<std::endl;
}

먼저 매개변수를 선언해 준 후 컴파일러는 해당 매개변수를 보고 decltype을 통해 data1+data2의 자료형을 추론한다. 

만약 auto 자리에 decltype(data1+data2)를 넣게 되면 컴파일러는 아직 data1과 data2의 매개변수 선언을 모르기 때문에 저런식으로 써줘야한다. 

 

템플릿 메타 프로그래밍

위의 템플릿을 이용하여 프로그래밍하는 방식이 있다. 해당 방식을 사용하면 모든 연산이 컴파일 타임에 수행되어 런타임때는 O(1)의 시간대로 처리 가능하다. 다만 컴파일 시간이 늘어나고 코드가 알아보기 힘들고 복잡해 진다. 디버깅도 힘들다. 정말 필요한 경우가 아니면 지양하는게 맞는거 같다.

#define FIBO(n) fibo <n>::val

template<unsigned N>
struct fibo
{
	enum {
		val = fibo<N-1>::val +fibo<N - 2>::val
	};
};
template<>
struct fibo<0>
{
	enum {
		val = 0
	};
};
template<>
struct fibo<1>
{
	enum {
		val = 1
	};
};


int main()
{
	cout << FIBO(10)<< endl;
}

해당 코드는 피보나치 수열을 구하는 코드를 템플릿 메타 프로그래밍으로 짠것이다. 컴파일 타임에서 변수 선언이 불가하기에 보통 상수가 되는 enum이나 const static을 사용한다. 종료 조건은 특수화 템플릿을 이용하였다. 

 

템플릿은 C++의 모든 STL에서 사용되는 아주 중요한 개념이다. 계속 쓰일 개념이니 꼭 숙지하고 있어야 겠다.

 

'언어 > C++' 카테고리의 다른 글

(C++)Vector / Deque  (0) 2020.09.14
(C++)STL  (0) 2020.09.14
(C++)함수 호출 규약  (0) 2020.07.13
(C++)함수 포인터와 콜백함수  (0) 2020.07.13
(C++)타입변환 연산자 오버로딩  (0) 2020.07.02