// template 탄생 배경
int square(int a)
{
return a * a;
}
double square(double d)
{
return d * d;
}
int main()
{
// 함수 오버로딩을 이용
// 이 square를 매번 개발자가 만들어 줘야할까?
square(3);
square(3.3);
}
개선해보자
#define MAKE_SQUARE(T) \
T square(T a) \
{ \
return a * a; \
}
MAKE_SQUARE(int)
MAKE_SQUARE(double)
int main()
{
square(3);
square(3.3);
}
좀더 그럴듯하게 개선을 못하나?
template<typename T>
T square(T a)
{
return a * a;
}
int main()
{
square<int>(3);
square<double>(3.3);
square(3); // ok - 컴파일러는 3이 int란걸알기에 가능
square(3.3); // ok!
}
- template은 진짜 함수가 아니라 함수를 만들어 내는 틀이다.
//template<typename T>
template<class T> //typename, class 모두 똑같은 기능을 한다.
T square(T a)
{
return a * a;
}
결론 : 그래서 언제쓰나?
class Complex
{
int re, im;
public:
Complex(double r, double i) : re(r), im(i) {}
// 받기는 double로 받는데 실제로 int네?? -> 이런실수가 나올 수 있다.
};
class Complex
{
int re, im;
public:
Complex(double r, double i) : re(r), im(i) {}
// 받기는 double로 받는데 실제로 int네?? -> 이런실수가 나올 수 있다.
};
class Test
{
public:
template<typename T> static void f() {}
template<typename T> class Complex {}
};
template<typename T> void foo(T a)
{
Test::f<int>(); // okay
T::f<int>(); // error - f가 template일지 아닐지 모르니 에러가 발생
T::template f<int>(); // okay - f가 template이라고 확실히 알려주면 okay
Test::Complex<int> c1; // okay
T::Complex<int> c2; // error - T가 자료형인지 모른다
typename T::Complex<int> c3; // error - Complex가 template인지 모른다
typename T::template Complex<int> c4; // ok
}
int main()
{
Test t;
foo(t);
}