[C++] 템플릿

강한·2025년 1월 23일

CPP

목록 보기
12/18
post-thumbnail

템플릿

  • 매개변수의 타입에 따라 함수나 클래스를 생성하는 매커니즘
  • 코드 중복을 줄이고, 여러 타입에서 동작하는 함수를 작성하거나 클래스를 만들 때 사용한다.
  • 특정 타입에 종속되지 않고 여러 타입을 수용할 수 있는 범용 코드를 작성할 수 있다.

함수 템플릿

  • 함수 자체를 일반화(generic)하여, 다양한 타입에 대해 같은 로직(동일한 처리)을 수행할 수 있도록 하는 것이다.
  • template <typename T> 이 부분이 템플릿 파라미터를 정의하는 부분이다.
  • 인자 타입에 따라 자동으로 템플릿 타입이 추론되는 경우가 많다.(템플릿 타입 추론)
  • 템플릿 파라미터를 여러 개 둘 수도 있다.
template<typename T>
void print(T a)
{
	cout << a << endl;
}

template<typename T1, typename T2>
void print(T1 a, T2 b)
{
	cout << a << " " << b << endl;	
}

template<typename T>
void print(int a)
{
	cout << "(int)" << a << endl;
}

int main()
{
	print<int>(1);
	print<float>(3.14f);
	print<const char*>("Hello");
	print<int, const char*>(1, "Hello");

}

클래스 템플릿

  • 클래스 자체를 일반화하여, 여러 타입의 객체를 다룰 수 있도록 만들어준다.
  • C++ 표준 라이브러리의 std::vector, std::list 등이 모두 클래스 템플릿입니다.
// 선언을 따로 안하면 기본 타입으로 int를 사용하겠다는 뜻, 뒤의 값도 동일
template<typename T = int, int SIZE = 200>
class RandomBox
{
public:
	T GetRandomData()
	{
		int index = rand() % SIZE;
		return data[index];
	}
public:
	T data[SIZE];
};
// 완전 특수화 때문에 <>안을 명시적으로 제거한다.
template<>
class RandomBox<float>
{
public:
	float GetRandomData()
	{
		int index = rand() % 100;
		return data[index];
	}
public:
	float data[100];
};

int main() 
{
	RandomBox<int, 100> r1;
	RandomBox<float> r2;
}
  • 클래스 템플릿을 헤더와 소스 파일로 분리하여 작성할 때는 주의가 필요하다.
  • 템플릿은 컴파일 시점에 구체화(Instantiating)되므로, 일반적인 클래스와는 달리 템플릿 선언과 정의가 분리되면 링크에 문제가 생길 수 있다.
  • 전통적으로는 헤더 파일에 모두 구현 을 하거나, 분리할 경우 template 와 같은 식으로 템플릿 파라미터를 포함한 정의를 .hpp나 .inl 형식으로 템플릿 소스에 넣고, 컴파일 단위에 포함시키는 식으로 처리해야 한다.

특수화

  • 일반 템플릿

    템플릿은 모든 타입과 크기에 대해 일반적인 형태를 정의합니다.
  • 완전 특수화

    	특정 타입(float)에 대해 별도의 완전한 정의를 제공합니다.	
    	template<>를 사용하여 일반 템플릿과의 연결을 명시적으로 제거합니다.
  • 부분 특수화

    	템플릿의 일부 매개변수를 특정 값으로 고정하거나 일부를 변경할 때 사용됩니다.
    	부분 특수화는 클래스 템플릿에만 사용할 수 있습니다.

주의점

  1. 컴파일 시간 증가
    • 템플릿은 컴파일 시점에 각 타입에 대해 코드가 생성됩니다. 코드 중복을 줄이지만, 컴파일러가 처리해야 할 일이 많아져서 빌드 시간이 길어질 수 있다.
  2. 오류 메세지 복잡
    • 템플릿을 사용할 때 발생하는 오류는 매우 길고 복잡한 템플릿 인스턴스화 메시지가 뜨는 경우가 많다.
  3. 헤더 파일에 구현
    • 템플릿은 선언부와 정의부를 분리하기 어렵고, 보통 헤더에 모두 정의하는 방식이 권장된다.
  4. 과도한 남발 금지
    • 템플릿은 편리하지만, 전역적으로 모든 타입에 대해 인스턴스화가 일어날 수 있으므로, 필요 이상의 템플릿 사용은 코드를 복잡하게 만들 수 있다.
profile
의지 강한 게임개발자

0개의 댓글