C++ 템플릿 Template

Intro

템플릿의 이해

템플릿 (Template)

템플릿은 함수나 클래스 코드를 찍어내듯이 생산할 수 있도록 일반화시키는 도구이다.

템플릿 구체화

템플릿으로 부터 함수를 만드는 과정을 구체화 또는 인스턴스화(Instantiation)라고 한다.

구체화 예시

1

과정

  1. 컴파일러가 myswap(a,b); 호출문을 컴파일할 때 myswap() 함수를 찾는다.

  2. 템플릿으로 선언된 myswap()함수를 발견한다.

  3. 실인자 a,b가 모두 int타입이므로 템플릿 제네릭타입 T에 int를 대입시켜 구체화된 myswap(int &a, int &b)를 만들어낸다.

  4. 구체화된 함수의 소스코드를 컴파일하고, 호출하도록 컴파일한다.

템플릿 역할

템플릿 함수는 컴파일되지도 호출되지도 않는 함수의 틀이다.

템플릿의 역할은 제네릭 함수를 선언하고, 컴파일 시점에 구체화하기 위한 틀을 제공하는 것이다.

함수 템플릿 예제

#include <iostream>
using namespace std;
class Circle
{
int radius;
public:
Circle(int radius = 1)
{
this->radius = radius;
}
int getRadius()
{
return radius;
}
};
template <class T>
void myswap(T&a, T&b)
{
T tmp;
tmp = a;
a = b;
b = tmp;
}
int main()
{
int a = 4, b = 5;
myswap(a, b);
cout << "a=" << a << ", " << "b=" << b << endl;
double c = 0.3, d = 12.5;
myswap(c, d);
cout << "c=" << c << ", " << "d=" << d << endl;
Circle donut(5), pizza(20);
myswap(donut, pizza);
cout << "donut반지름=" << donut.getRadius() << ", ";
cout << "pizza반지름=" << pizza.getRadius() << endl;
}
view raw template.cpp hosted with ❤ by GitHub

템플릿에 의해 여러 타입의 제네릭 함수가 만들어진다.

실행 결과

a=5, b=4
c=12.5, d=0.3
donut반지름=20, pizza반지름=5

클래스 타입도 매개 변수로 구체화 할 수 있음을 보여준다.

명시적 특수화(Explicit Specialization)

C++의 함수 템플릿은 특정 타입에 대한 명시적 특수화를 제공하여, 해당 타입에 대해 특별한 동작을 정의 할수 있다.

double형에 대한 명시적 특수화 예제

#include <iostream>
using namespace std;
template <class T>
void myswap(T&a, T&b)
{
T tmp;
tmp = a;
a = b;
b = tmp;
}
template <> void myswap<double>(double&, double&)
{
};
int main()
{
int a = 4, b = 5;
myswap(a, b);
cout << "a=" << a << ", " << "b=" << b << endl;
double c = 0.3, d = 12.5;
myswap(c, d);
cout << "c=" << c << ", " << "d=" << d << endl;
}

실행결과

a=5, b=4
c=0.3, d=12.5

double형은 값을 바꾸지 않음을 확인할 수 있다.

클래스 템플릿

클래스도 함수와 마찬가지로 템플릿으로 정의가 가능하다.

클래스 템플릿 예시

template <typename 타입이름>

class 클래스템플릿이름

{

    // 클래스 멤버의 선언

}

클래스 템플릿 예제

#include <iostream>
using namespace std;
template <typename T>
class Point
{
private:
T xPos, yPos;
public:
Point(T x = 0, T y = 0)
: xPos(x), yPos(y)
{ }
void ShowPosition() const
{
cout << '[' << xPos << ", " << yPos << ']' << endl;
}
};
int main(void)
{
Point<int> pos1(3, 4);
pos1.ShowPosition();
Point<double> pos2(2.4, 3.6);
pos2.ShowPosition();
Point<char> pos3('P', 'F');
pos3.ShowPosition();
return 0;
}

실행 결과

[3, 4]
[2.4, 3.6]
[P, F]

제네릭 클래스를 이용할 때에는 클래스의 이름과 함께 제네릭 타입 T에 구체적 타입을 지정해줘야 한다.

참고 자료

황기태, 명품 C++ Programming, 생능출판사,2013, 463쪽

http://tcpschool.com/cpp/cpp_template_class

https://blog.naver.com/sonicheroes1/220927511175

태그: ,

카테고리:

업데이트:

댓글남기기