C++
템플릿의 정의를 CPP에 쓸 수 없는 이유
Keisa
2024. 7. 25. 16:28
일반 함수
일반 함수의 경우, 함수 선언과 정의를 분리하는 것이 일반적입니다. 함수 선언은 헤더 파일에 있고, 정의는 소스 파일에 있습니다. 예를 들어:
// myfunctions.h
void myFunction();
// myfunctions.cpp
#include "myfunctions.h"
void myFunction()
{
// 함수 정의
}
컴파일러는 각 소스 파일을 독립적으로 컴파일한 후, 링커가 모든 객체 파일을 결합하여 프로그램을 만듭니다. 이 과정에서 링커는 함수 선언과 정의를 연결합니다. 링커는 함수의 선언이 포함된 객체 파일에서 함수 호출을 발견하고, 함수 정의가 포함된 다른 객체 파일에서 이를 찾아 연결합니다.
템플릿 함수
템플릿 함수의 경우, 상황이 달라집니다. 템플릿은 사용될 때마다 컴파일러가 인스턴스화하여 실제 코드를 생성합니다. 즉, 템플릿의 정의는 템플릿이 사용되는 모든 파일에서 접근할 수 있어야 합니다. 다음 예를 보겠습니다:
// mytemplate.h
template <typename T>
void myTemplateFunction(T value);
// mytemplate.cpp
#include "mytemplate.h"
template <typename T>
void myTemplateFunction(T value)
{
// 템플릿 함수 정의
}
템플릿 함수가 다른 파일에서 사용될 때, 컴파일러는 myTemplateFunction<int>과 같은 구체적인 인스턴스를 생성해야 합니다. 하지만 이 경우, 템플릿 함수의 정의가 .cpp 파일에 있으므로, 다른 파일에서는 이를 찾을 수 없습니다. 따라서 컴파일러는 템플릿 인스턴스를 생성할 수 없게 됩니다.
해결 방법
템플릿 함수의 정의를 헤더 파일에 포함시켜야 합니다. 이렇게 하면 템플릿이 사용될 때마다 컴파일러가 정의를 확인하고 인스턴스를 생성할 수 있습니다. 예를 들어:
// mytemplate.h
template <typename T>
void myTemplateFunction(T value)
{
// 템플릿 함수 정의
}
이렇게 하면, 템플릿 함수가 사용될 때마다 컴파일러가 헤더 파일을 참조하여 인스턴스를 생성할 수 있습니다.
요약
- 일반 함수: 함수 정의가 컴파일러 단계에서 별도로 컴파일되고, 링커가 이를 결합합니다.
- 템플릿 함수: 템플릿의 정의가 사용될 때 인스턴스화되므로, 정의가 사용될 파일에서 항상 접근 가능해야 합니다. 따라서 템플릿 정의는 헤더 파일에 포함되어야 합니다.
- 일반 함수는 헤더와 cpp를 별도로 컴파일하여 링커를 이용해 링킹작업을 수행, 그러나 템플릿함수는 컴파일 타임에 템플릿을 사용하는 곳에서 템플릿 인스턴스화를 통해 실제 코드를 생성해야하므로 정의를 분리하여 cpp에 둘 수 없다.