[C/C++ 강좌] 91강. 템플릿 (1) - 함수 템플릿과 클래스 템플릿
https://www.youtube.com/watch?v=Pg-3Fzp5G7k&list=PLlJhQXcLQBJqywc5dweQ75GBRubzPxhAk&index=96
1. 함수 템플릿
#include <iostream>
using namespace std;
int getArraySum(const int arr[], int n) {
int sum = 0;
for (int i = 0; i < n; i++) { // i가 0부터 시작
sum += arr[i];
}
return sum;
}
위와같이 int형 배열의 합을 구하는 함수를 정의했다고 쳤을 때 나중에 float형, double형 더 나아가서 개발자가 정의한 형에 대해서의 배열도 표현하고 싶다면 오버로딩을 통해 정의하는 방법이 있다.
하지만 자료형이 계속 늘어날 때마다 개발자가 매번 정의 해야하는 것은 유지보수 측면에서도 좋지 못하다.
그러한 것을 해결하기 위해 C++에서는 템플릿 기능을 지원한다.
template<typename T>
T getArraySum(const T arr[], int n) {
T sum = T(); // 기본생성자 호출 int형 같은 경우에는 0이 들어감
for (int i = 1; i < n; i++) { // i가 0이 아닌 1부터 시작
sum += arr[i];
}
return sum;
}
위 코드는 템플릿을 이용하여 배열의 합 출력하는 함수이다. T로 정의했기 때문에 T를 통해 자료형이 치환되어서 코드가 실행이 된다.
사용방법은 다음과 같다.
int main() {
int iarr[5] = { 3, 1, 4, 1, 5 };
float farr[5] = { 3.1, 1.2, 4.3, 1.4, 5.5 };
Vector2 varr[3] = { Vector2(1, 2), Vector2(3, 4), Vector2(5, 6) }; // 정의한 자료형
int isum = getArraySum<int>(iarr, 5);
float fsum = getArraySum<float>(farr, 5);
Vector2 vsum = getArraySum<Vector2>(varr, 5);
}
<자료형>을 템플릿 인수라고하는데 템플릿 인수를 통해서 넣을 자료형을 명시해주면된다. 그리고 템플릿 인수를 생략할 수 있는데 매개변수를 통해 컴파일러에서 자동으로 템플릿 인수의 자료형을 유추한다.
그런데 getArraySum함수에는 한가지 사소한 문제점이 있다.
내가 정의한 함수에는 += 연산을 지원하지 않는다는 점이다.
sum += arr[i];
이러한 문제점은 연산자 오버로딩을 통해서 해결해주면 된다.
2. 클래스 템플릿
class Vector2 {
public:
Vector2() : x(0), y(0) {}
Vector2(float x, float y) : x(x), y(y) {}
float GetX() const { return x; }
float GetY() const { return y; }
Vector2 operator+(const Vector2& rhs) const {
return Vector2(x + rhs.x, y + rhs.y);
}
Vector2 operator-(const Vector2& rhs) const {
return Vector2(x - rhs.x, y - rhs.y);
}
Vector2& operator+=(const Vector2& rhs) {
x += rhs.x;
y += rhs.y;
return *this;
}
Vector2& operator-=(const Vector2& rhs) {
x -= rhs.x;
y -= rhs.y;
return *this;
}
private:
float x, y;
};
위 클래스의 멤버들은 float형으로 이루어져있다. 이것을 int형이나 double형 등에도 똑같은 기능으로 쓰고 싶은 경우가 있을 수 있다. 그럴 때 클래스 템플릿을 사용하면된다.
template<typename T>
class Vector2 {
public:
Vector2() : x(0), y(0) {}
Vector2(T x, T y) : x(x), y(y) {}
T GetX() const { return x; }
T GetY() const { return y; }
Vector2 operator+(const Vector2& rhs) const {
return Vector2(x + rhs.x, y + rhs.y);
}
Vector2 operator-(const Vector2& rhs) const {
return Vector2(x - rhs.x, y - rhs.y);
}
Vector2& operator+=(const Vector2& rhs) {
x += rhs.x;
y += rhs.y;
return *this;
}
Vector2& operator-=(const Vector2& rhs) {
x -= rhs.x;
y -= rhs.y;
return *this;
}
private:
T x, y;
};
사용방법은 다음과 같다.
int main() {
Vector2<int> varr[3] = { Vector2<int>(1, 2), Vector2<int>(3, 4), Vector2<int>(5, 6) };
Vector2<int> vsum = getArraySum<Vector2<int>>(varr, 5);
}
클래스명<자료형>형식으로 사용하며 함수템플릿과 달리 템플릿 인수의 생략이 불가능하다.