카테고리 없음

#코딩연습 4 템플릿

마쿠어 2023. 5. 30. 00:44
#include <iostream>
using namespace std;

template <class T>
				class CPoint{
				private:
                T x, y;
                public:
                CPoint(T a, T b) : x(a), y(b) {}

                template <class T2>
                        friend ostream& operator<<(ostream&, CPoint<T2>);
};

template <class T>
ostream& operator <<(ostream& os, CPoint<T> pt)
{
        os << "(" << pt.x << "," << pt.y << ")" << endl;
        return os;
}

int main(void)
{
        CPoint<int> P1(1,2);
        CPoint<double> P2(1.1, 2.2);

        cout << P1 << P2;
        return 0;
}

위의 코드에서 나는 왜 굳이 type이 T와 T2로 구분되는지에 의문점을 가지게 되었다. 이유는 다음과 같다.

 

먼저 위의 함수가 작동하는 방식은 먼저 class CPoint 정의하는데에 있다. 여기서는 T형 변수를 활용하게 된다. 즉, CPoint<T> 형 객체가 생성되는 것이다. <<<여기서 class 와 typename은 동일한 기능을 한다>>>

 

일단 위의 경우 출력부와 객체 선언부의 동일한 매개인 class T는 충돌하지 않는다. 서로 작동이 될 시기에는 다른 한 쪽이 휘발되므로 T에서 충돌 x ~> 실제로 출력부의 매개변수를 T3로 바꿔도 동일하게 작동한다. ~> 결국 하나의 템플릿 내에서 충돌이 일어나지만 않으면 된다.

 

그러면 객체 선언부에서 CPoint<int>를 예시로 두면 T = int가 된다. 덕분에 P1은 정수형 좌표가 입력이 된다.

 

그러면 T2가 사용되는 지점은 출력부에 있다. 출력은 cout << P1과 cout << P2는 분리되어 사용이 되니 신경 x

 

***T와 T2는 템플릿 안에 템플릿이 있으므로 이 둘을 구분하기 위한 요소이다. template<class T> 로 틀의 이름이 선언되었는데, 그 안에서 다시 동일한 이름으로 선언하는 꼴이다.

마치 너 안에 너가 있다 이런 의미로 오류가 발생하는 것이다.

결국 이러한 중복을 피하기 위해서 구분을 둔 것이다. 아래서 int, double이 있고 말고는 영향을 주지 않는다.

 

첨언하자면, template<class T> 안에서 동일한 template<class T> 선언을 한 것이 문제이다. 선언을 하는 중에 자기 자신을 다시 선언한다는게 얼마나 잘못된건지 알겠지?