일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- jupyter
- Algorithm
- 다트 언어
- gitlab
- git
- c# 추상 클래스
- C언어 포인터
- docker
- c# winform
- Python
- github
- HTML
- 포인터
- c# 윈폼
- jupyter lab
- Unity
- vim
- 구조체
- c언어
- 플러터
- Data Structure
- 유니티
- C# delegate
- Houdini
- C++
- 깃
- dart 언어
- 도커
- Flutter
- c#
- Today
- Total
nomad-programmer
[Programming/C++] 템플릿 인자 본문
템플릿을 정의할 때 결정되지 않은 자료형을 의미하는 용도로 사용되는 T 또는 T1, T2와 같은 문자를 가리켜 '템플릿 매개변수' 라 한다.
그리고 템플릿 매개변수에 전달되는 자료형 정보를 가리켜 '템플릿 인자' 라 한다.
템플릿 매개변수에는 변수의 선언이 올 수 있다.
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은 해당 템플릿 클래스에서 상수처럼 사용된다.
즉, len은 각각 5와 7로 치환되어, 컴파일러에 의해 다음과 같이 SimpleArray<int, 5> 형 템플릿 클래스와 SimpleArray<double, 7> 형 템플릿 클래스가 각각 생성된다.
class SimpleArray<int, 5> {
private:
int arr[5];
public:
int& operator[] (int idx) {
return arr[idx];
}
};
class SimpleArray<int, 7> {
private:
int arr[7];
public:
int& operator[] (int idx) {
return arr[idx];
}
};
물론 위의 두 템플릿 클래스 SimpleArray<int, 5>와 SimpleArray<double, 7>은 서로 다른 자료형의 클래스로 구분된다.
다음의 예제를 살펴보자.
#include <iostream>
#pragma warning(disable: 4996)
using std::cout;
using std::cin;
using std::endl;
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) {
for (int i = 0; i < len; i++) {
arr[i] = ref.arr[i];
}
return *this;
}
};
int main(const int argc, const char* const argv[]) {
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;
}
/* 결과
0, 10, 20, 30, 40,
0, 10, 20, 30, 40, 50, 60,
*/
i5arr1과 i5arr2가 모두 SimpleArray<int, 5>형이기 때문에 대입연산이 가능하다.
i7arr1과 i7arr2가 모두 SimpleArray<int, 7>형이기 때문에 대입연산이 가능하다.
그리고 이 예제에서 중요한 것은 다음과 같다.
SimpleArray<int, 5>와 SimpleArray<int, 7>은 서로 다른 형(type)이다.
때문에 길이가 다른 두 배열 객체간의 대입은 허용되지 않는다. 즉, 다음의 대입연산에서는 컴파일 에러가 발생한다.
int main(void) {
SimpleArray<int, 5> i5arr;
SimpleArray<int, 7> i7arr;
i5arr = i7arr;
return 0;
}
이렇듯, 템플릿 매개변수에 값을 전달받을 수 있는 변수를 선언하면, 변수에 전달되는 상수를 통해서 서로 다른 형의 클래스가 생성되게 할 수 있다.
따라서 위 예제의 경우, 길이가 다른 두 배열 객체간의 대입 및 복사에 대한 부분을 신경 쓰지 않아도 된다.
만약 생성자를 이용해서 배열의 길이를 결정하게 했다면, 길이가 같은 배열에 대해서만 대입을 허용하기 위해서 추가적인 코드의 삽입이 불가피하며, 이러한 추가적인 코드는 대입 및 복사의 과정에서 CPU가 수행해야 할 일을 늘리는 결과로 이어진다.
템플릿 매개변수는 디폴트 값 지정도 가능하다.
함수의 매개변수에 디폴트 값의 지정이 가능하듯이, 템플릿 매개변수에도 디폴트 값의 지정이 가능하다.
#include <iostream>
#pragma warning(disable: 4996)
using std::cout;
using std::cin;
using std::endl;
// Default 값 지정
template <typename T = int, 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(const int argc, const char* const argv[]) {
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;
}
/* 결과
1 2 3 4 5 6 7
*/
template <typename T = int, int len = 7>
템플릿 매개변수에 디폴트 값이 지정되어도, 템플릿 클래스의 객체생성을 의미하는 <> 기호는 반드시 추가되어야 한다. 비록 그 안을 비워둘지라도 말이다.
'Programming > C++' 카테고리의 다른 글
[Programming/C++] C++에서의 형 변환 연산 (0) | 2021.02.08 |
---|---|
[Programming/C++] 템플릿과 static (0) | 2021.02.07 |
[Programming/C++] 클래스 템플릿의 특수화(Class Template Specialization) (0) | 2021.02.07 |
[Programming/C++] 클래스 템플릿(Class Template) (0) | 2021.02.07 |
[Programming/C++] 함수 템플릿과 특수화(Specialization) (0) | 2021.02.06 |