728x90

Template Build (Instantiation)은 C++ 코드를 짤 때 Header와 Cpp파일을 분리해서 코드를 따게 되는데 Template 함수를 Header에 Declaration을 하고 Cpp파일에 Definition을 하고 컴파일을 하면 에러가 뜨고 컴파일이 되지 않는다. 해당 문제가 왜 발생하는지 알아보자. 

 

 

Template Instantiation (템플릿 인스턴스화)

 

템플릿 인스턴스화에는 크게 아래 두 가지 종류가 있다. 

  • Implicit Instantiation (암시적 인스턴스화)
  • Explicit Instantiation (명시적 인스턴스화)

 

 

Implicit Instantiation (암시적 인스턴스화)는 우리가 Template함수를 정의하고 main함수에서 Angle Bracket으로 차입을 명시해주어 함수를 호출하는 방식을 말한다. 암시적 인스턴스화는 두 가지가 있는데 다 이미 배웠던 내용이다. 

 

코드를 통해서 두 가지 암시적 인스턴스화에 대해서 알아본다. 

 

암시적 인스턴스화는 두 가지가 있다. 

  • 사용자가 Angle Bracket ('<', '>')에 Type을 명시해주는 방법
  • Template Type Deduction (타입 추론)을 이용해 Type을 명시하지 않는 방법
#include <iostream>

template<typename T>
T foo(T a)
{
	std:::cout << a << '\n';
}
int main()
{
	foo<int>(12);	//사용자가 Type을 직점 Angle Bracket에 넣어주는 방법

	foo(12);	//Template Type Deduction을 이용해 Type을 명시해주지 않는 방법

	return 0;
}

 

Template 함수는 함수를 호출(인스턴스화) 하기 전까지 코드로 존재하다가 인스턴스 화가 되면서 해당 Type혹은 Deduction을 통해서 함수를 만들게 된다. 

 

그렇다면 Header 파일에 Template함수에 대한 Declaration을 작성하고 Cpp 파일에  Definition을 작성하게 되면 정상적으로 코드가 동작하는지 확인해보자. 

 

main.cpp

#include <iostream>

int main()
{
	foo<int>(12);	//사용자가 Type을 직점 Angle Bracket에 넣어주는 방법

	foo(12);	//Template Type Deduction을 이용해 Type을 명시해주지 않는 방법

	return 0;
}

 

foo.h

#pragma once
template<typename T>
T foo(T a);

 

foo.cpp

template<typename T>
T foo(T a)
{
	std:::cout << a << '\n';
}

 

위와 같이 Template 함수의 Declaration를 foo.h에 함수의 Definition을 foo.cpp에 적는다면 컴파일 에러가 나게 된다. 컴파일 에러가 나게 되는 이유는 Template는 함수 자체가 아니고 컴파일러가 Instantiation이 발생하면 코드로 만들어주는 기능을 하게 된다. 여기서 Template을 보고 코드를 만들게 되는데 foo.h에 있는 내용 즉 Declaration만 보고는 어떠한 코드를 만들지를 모르기 때문에 컴파일 에러가 난다. 

 

위 에러를 해결하기 위해서 두 가지 방법을 사용할 수 있는데 코드로 알아본다. 

 

main.cpp

#include <iostream>

int main()
{
	foo<int>(12);	//사용자가 Type을 직점 Angle Bracket에 넣어주는 방법

	foo(12);	//Template Type Deduction을 이용해 Type을 명시해주지 않는 방법

	return 0;
}

 

foo.h

#pragma once
template<typename T>
T foo(T a)
{
	std:::cout << a << '\n';
}

 

위와 같이 cpp파일에 Definition을 따로 적지 않고 header 파일에 정의까지 해주는 방법이 있다. 

 

굳이 cpp 파일에 정의를 해서 코드를 만들고 싶다면 cpp 파일 안에 Type Explicit Instantiation을 하면 문제가 해결된다. 이 뜻은 무엇이냐면 cpp 파일 안에 특정 Type에 대한 함수로 컴파일을 해달라고 요청한다고 생각하면 된다. 하지만 이럴 경우 사용하고자 하는 Type에 대해서 모두 Explicit 하게 선언을 해주어야 한다. 

 

main.cpp

#include <iostream>

int main()
{
	foo<int>(12);	//사용자가 Type을 직점 Angle Bracket에 넣어주는 방법

	foo(12);	//Template Type Deduction을 이용해 Type을 명시해주지 않는 방법

	return 0;
}

 

foo.h

#pragma once
template<typename T>
T foo(T a);

 

foo.cpp

template<typename T>
T foo(T a)
{
	std:::cout << a << '\n';
}

template int foo<int>(int);	//explicit template instatiation

 

+ Recent posts