[문과 코린이의 IT 기록장] C++ - 템플릿 인자 (템플릿 매개변수의 변수 선언, 템플릿 매개변수에 디폴트 값 지정)
[문과 코린이의 IT 기록장] C++ - 템플릿 인자 (템플릿 매개변수의 변수 선언, 템플릿 매개변수에 디폴트 값 지정)
[ 클래스 템플릿에 대한 이전 포스팅 ]
1. 템플릿 매개변수에는 변수의 선언이 올 수 있다.
# 템플릿 매개변수 : T1, T2와 같은 문자들
ex )
template <typename T, int len>
class SimpleArray{
private:
T arr[len];
public:
T& operator[] (int idx){
return arr[idx];
}
}
이 정의를 보면, 템플릿 매개변수의 선언에 마치 함수처럼 변수의 선언이 나타난다.
이와같이 템플릿 매개변수에도 변수가 올 수 있으며, 다음과 같은 형태로 객체생성 또한 가능하다.
SimpleArray<int,5> i5arr;
SimpleArray<double,7) d7arr;
위 문장에서 템플릿 매개변수 len에 전달된 인자 5,7은 해당 템플릿 클래스에서 상수처럼 사용된다.
// <int,5>
class SimpleArray<int, 5>
{
private:
int arr[5];
public:
int& operator[] (int idx) {return arr[idx];)
};
// <double,7>
class SimpleArray<double, 7>
{
private:
double arr[7];
public:
double& operator[] (int idx) {return arr[idx];)
};
Case 1 )
템플릿 매개변수에 정수를 전달하는 작업은, 마치 생성자를 이용해서 배열의 길이를 결정하는 것과 비슷하다.
따라서 생성자를 이용해는게 더 편리할 수도 있는데, 그렇다면 왜 템플릿 매개변수에 정수를 전달하는 작업은 문법적으로 왜 필요한 것일까?
#include<iostream>
using namespace std;
template <typename T, int len>
class SimpleArray {
private:
T arr[len];
public:
T& operator[](int idx) { return arr[idx]; }
SimpleArray<T, len>& operator=(const SimpleArray<T, len>& ref)
// 대입연산자
// 매개변수로 들어오는 SimpleArray<T,len>형의 객체 &ref는 값이 변화하면 안되므로 const 붙여주기
// 반환형 : 참조형 (SimpleArray<T,len>&)
{
for (int i = 0; i < len; i++) {
arr[i] = ref.arr[i];
}
return *this;
}
};
int main() {
SimpleArray<int, 5> i5arr1;
for (int i = 0; i < 5; i++) {
i5arr1[i] = i * 10;
}
SimpleArray<int, 5> i5arr2;
i5arr2 = i5arr1;
for (int i = 0; i < 5; i++) {
cout << i5arr2[i] << ", ";
}
cout << endl;
SimpleArray<int, 7> i7arr1;
for (int i = 0; i < 7; i++) {
i7arr1[i] = i * 10;
}
SimpleArray<int, 7> i7arr2;
i7arr2 = i7arr1;
for (int i = 0; i < 7; i++) {
cout << i7arr2[i] << ", ";
}
cout << endl;
return 0;
}
위 예제에서 주목할 사실은 SimpleArray<int,5>와 SimpleArray<int,7>은 서로 다른 형(type)이라는 것이다.
따라서 길이가 다른 두 배열 객체간의 대입은 허용되지 않기때문에, 다음과 같은 코드에서는 컴파일 에러가 발생한다.
int main()
{
SimpleArray<int,5> i5arr1;
SimpleArray<int,7> i7arr1;
i5arr1 = i7arr1; // 컴파일 에러 발생
...
}
따라서 위 예제에서는 자료형 및 길이가 같은 배열 객체에 대해서만 대입 및 복사가 허용되니, 이러한 부분에 대한 오류는 고려하지 않아도 된다.
그러나 생성자를 이용해서 배열의 길이를 결정하게 된다면, 길이가 같은 배열에 대해서만 대입을 가능하도록 하는 추가적인 코드를 꼭 삽입해야 할 것이다. 즉 이는 CPU가 수행해야 할 일을 늘리는 것이다.
2. 템플릿 매개변수는 디폴트 값 지정도 가능하다.
Case 2 )
#include<iostream>
using namespace std;
template <typename T=int, int len =7> // Default Value 지정
// 즉, T에 int가, len에 7 값이 디폴트 값으로 지정되었다.
class SimpleArray {
private:
T arr[len];
public:
T& operator[] (int idx) { return arr[idx]; }
SimpleArray<T, len>& operator=(const SimpleArray<T, len>& ref) {
for (int i = 0; i < len; i++) {
arr[i] = ref.arr[i];
}
return *this;
}
};
int main() {
SimpleArray<> arr;
// 디폴트 값을 이용한 객체의 생성
// 디폴트 값이 지정될 경우에도, 탬플릿 클레스의 객체생성을 의미하는 <> 기호는 적어줘야 함
for (int i = 0; i < 7; i++) {
arr[i] = i + 1;
}
for (int i = 0; i < 7; i++) {
cout << arr[i] << " ";
}
cout << endl;
return 0;
}
* 유의사항 - 아직 공부하고 있는 문과생 코린이가, 정리해서 남겨놓은 정리 및 필기노트입니다. - 정확하지 않거나, 틀린 점이 있을 수 있으니, 유의해서 봐주시면 감사하겠습니다. - 혹시 잘못된 점을 발견하셨다면, 댓글로 친절하게 남겨주시면 감사하겠습니다 :) |