ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [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;
    }

     

Designed by Tistory.