-
[C/C++ 강좌] 92강. 템플릿 (2) - 템플릿 특수화와 비타입 파라미터C++ 2022. 1. 22. 13:44
https://www.youtube.com/watch?v=_fh44DhlHEI&list=PLlJhQXcLQBJqywc5dweQ75GBRubzPxhAk&index=97
1. 템플릿 특수화
template<typename T> T getArraySum(const T arr[], int n) { T sum = 0; for (int i = 1; i < n; i++) { sum += arr[i]; } return sum; }
위와 같은 코드가 있을 때 모든 자료형을 만족시킬 수는 없다. 오버로딩과 비슷한 느낌으로 템플릿 특수화는 특정한 자료형에 대해 재정의를 하여 다르게 동작할 수 있다.
template<> string getArraySum<string>(const string arr[], int n) { string sum = arr[0]; for (int i = 1; i < n; i++) { sum += ' ' + arr[i]; } return sum; }
사용방법은 위와같다. 변경할 부분에 대해서는 재정의해주면 된다.
2. 비타입 파라미터
#include <iostream> using namespace std; template<typename T> class Vector { public: Vector(int n) { this->n = n; comp = new T[n]; } ~Vector() { delete[] comp; } T GetComp(int i) const { // i번째 성분을 리턴 return comp[i]; } void SetComp(int i, T val) { comp[i] = val; } Vector operator+(const Vector& rhs) const { } private: int n; // 벡터의 차원 T *comp; // 벡터의 성분 }; int main() { Vector<float> v(3); v.SetComp(0, 2); v.SetComp(1, 3); v.SetComp(2, 4); cout << v.GetComp(0) << ", " << v.GetComp(1) << ", " << v.GetComp(2) << endl; }
위 Vector클래스는 멤버변수로 차원(n)과 성분(comp)을 갖는 클래스이다.
그런데 벡터끼리 합을 해주는 연산은 연산자 오버로딩을 통해서 해결할 수 있는 반면에 실수로 서로 차원이 다른 벡터끼리의 합을 해주는 연산을 사용자가 실수로 사용했다고 쳤을 때 이러한 것들을 문법적으로 막을 수는 없다.
이러한 문제점을 효과적으로 해결할 수 있는 방법이 비타입 파마미터이다.
template<typename T, int n> class Vector { public: Vector() { this->n = n; comp = new T[n]; } ~Vector() { delete[] comp; } T GetComp(int i) const { // i번째 성분을 리턴 return comp[i]; } void SetComp(int i, T val) { comp[i] = val; } Vector operator+(const Vector<T, n>& rhs) const { Vector res; for (int i = 0; i < n; i++) res.comp[i] = this->comp[i] + rhs.comp[i]; return res; } private: // 벡터의 차원 T *comp; // 벡터의 성분 };
벡터의 차원을 나타내는 성분인 int n을 템플릿 인수로 넣어주었다. 그리고 +연산자 오버로딩에서 템플릿을 인수를 통해 서 같은 차원끼리만 연산이 가능하게 바뀌었다.
그리고 비타입 파라미터로 코드를 정의한 다음 아래와 같은 코드를 작성하면 구문 오류가 발생한다.
int main() { Vector<float, 3> v1, v2; Vector<float, 2> v3; v1.SetComp(0, 2); v1.SetComp(1, 3); v1.SetComp(2, 4); v2 = v1 + v3; // <float, 3> 과 <float, 2>는 연산이 불가능하므로 구문오류발생 cout << v1.GetComp(0) << ", " << v1.GetComp(1) << ", " << v1.GetComp(2) << endl; }
'C++' 카테고리의 다른 글
[C/C++ 강좌] 94강. 함수 포인터 (0) 2022.01.22 [C/C++ 강좌] 93강. 예외 처리 (0) 2022.01.22 [C/C++ 강좌] 91강. 템플릿 (1) - 함수 템플릿과 클래스 템플릿 (0) 2022.01.22 [C/C++ 강좌] 90강. 정사각형-직사각형 문제 (0) 2022.01.21 [C/C++ 강좌] 89강. 다중 상속과 다이아몬드 문제 (0) 2022.01.21