728x90
황기태 저자의 명품 C++ Programming 개정판을 읽고 학습한 내용을 정리한 포스트입니다!
https://search.shopping.naver.com/book/catalog/32436115747
하나의 제네릭 타입을 가진 경우
두 개의 매개 변수로 부터 큰 값 구하기
- 두 수를 매개 변수로 받아 큰 값을 리턴하는 제네릭 함수 bigger()를 만들어 보자.
- bigger()는 2개의 매개 변수와 리턴 타입이 동일하므로, bigger() 함수의 템플릿 원형은 다음과 같이 선언
template <class T>
T bigger(T a, T b) // 두 개의 매개 변수 a, b를 비교하여 큰 값 리턴
#include <iostream>
using namespace std;
template <class T>
T bigger(T a, T b) { // 두 개의 매개 변수를 비교하여 큰 값을 리턴
if(a > b) return a;
else return b;
}
int main() {
int a=20, b=50;
char c='a', d='z';
cout << "bigger(20, 50)의 결과는 " << bigger(a, b) << endl;
cout << "bigger('a', 'z')의 결과는 " << bigger(c, d) << endl;
}
배열의 합 구하기
- 배열을 매개 변수로 받아 합을 구하여 리턴하는 제네릭 함수 add()를 만들어보자.
- add()는 int, long, double 배열을 다 더할 수 있다.
- 첫 번째 매개 변수에는 배열이 전달되지만, 두 번재 매개 변수는 배열의 타입에 관계없이 배열의 크기가 전달되므로 항상 int 타입
template <class T>
T add(T data [], int n) // data [] 배열에서 n개의 원소를 합한 결과 리턴
#include <iostream>
using namespace std;
template <class T>
T add(T data [], int n) { // 타입 T의 배열 data에서 n개의 원소를 합한 결과를 리턴
T sum = 0;
for(int i=0; i<n; i++) {
sum += data[i];
}
return sum; // sum와 타입과 리턴 타입이 모두 T로 선언되어 있음
}
int main() {
int x[] = {1,2,3,4,5};
double d[] = {1.2, 2.3, 3.4, 4.5, 5.6, 6.7};
cout << "sum of x[] = " << add(x, 5) << endl; // 배열 x와 원소 5개의 합을 계산
cout << "sum of d[] = " << add(d, 6) << endl; // 배열 d와 원소 6개의 합을 계산
}
두 개 이상의 제네릭 타입을 가진 경우
- 두 개 이상의 제네릭 타입을 가진 제네릭 함수를 만들 수 있다.
- 하나의 배열을 다른 타입의 배열로 변환하여 복사하는 mcopy() 함수를 템플릿으로 만들어보자.
template <class T1, class T2>
void mcopy(T1 src [], T2 dest [], int n) // n은 복사할 원소의 개수
- mcopy()는 src[] 배열에서 n개의 원소만 dest[] 배열에 복사
- src[] 타입은 T1, dest[] 타입은 T2로 서로 다르기 때문에 mcopy() 호출 시, 두 매개 변수에 동일한 타입의 배열을 넘길 수도 있고, 다른 타입의 배열을 넘길 수도 있다.
#include <iostream>
using namespace std;
// 두 개의 제네릭 타입 T1, T2를 가지는 copy()의 템플릿
template <class T1, class T2>
void mcopy(T1 src [], T2 dest [], int n) { // src[]의 n개 원소를 dest[]에 복사하는 함수
for(int i=0; i<n; i++)
dest[i] = (T2)src[i]; // T1 타입의 값을 T2 타입으로 변환한다.
}
int main() {
int x[] = {1,2,3,4,5};
double d[5];
char c[5] = {'H', 'e', 'l', 'l', 'o'}, e[5];
mcopy(x, d, 5); // int x[]의 원소 5개를 double d[]에 복사
mcopy(c, e, 5); // char c[]의 원소 5개를 char e[]에 복사
for(int i=0; i<5; i++) cout << d[i] << ' '; // d[] 출력
cout << endl;
for(int i=0; i<5; i++) cout << e[i] << ' '; // e[] 출력
cout << endl;
}
/*
1 2 3 4 5
H e l l o
*/
중복 함수가 템플릿 함수보다 우선
- 배열을 출력하는 템플릿 함수 print()를 만들어보자.
#include <iostream>
using namespace std;
template <class T>
void print(T array [], int n) {
for(int i=0; i<n; i++)
cout << array[i] << '\t';
cout << endl;
}
int main() {
int x[] = {1,2,3,4,5};
double d[5] = { 1.1, 2.2, 3.3, 4.4, 5.5 };
print(x, 5); // 템플릿으로부터 구체화한 함수 호출
print(d, 5); // 템플릿으로부터 구체화한 함수 호출
char c[5] = {1,2,3,4,5};
print(c, 5); // char 배열을 숫자로 출력하는 중복 함수 호출
}
/*
1 2 3 4 5
1.1 2.2 3.3 4.4 5.5
┌ 」
*/
- 템플릿 print()의 목적은 int 배열이든, double이든 char이든 배열에 들어 있는 숫자를 출력하는데 있다.
- 위의 코드에서 int 배열과 double 배열을 출력하는데에는 문제가 없지만, char 배열로 print()를 호출 시 문제가 발생한다.
- 제네릭 타입 T가 char 타입으로 구체화되어 연산자가 array[i] 값을 문자로 출력하는데 1, 2, 3, 4, 5 정수 값에 해당하는 ASCII 문자가 없기 때문에 윈도우 운영체제의 문자 코드표에 정의된 그래픽 문자를 출력한다.
이를 해결하기 위해서는 char 배열의 정수를 출력하는 print()를 템플릿 함수와 중복 작성하면 된다.
- 템플릿 함수와 이름이 동일한 함수가 중복되어 있을 때, 컴파일러는 중복된 함수를 템플릿 함수보다 우선하여 바인딩한다.
#include <iostream>
using namespace std;
template <class T>
void print(T array [], int n) {
for(int i=0; i<n; i++)
cout << array[i] << '\t';
cout << endl;
}
void print(char array [], int n) { // 템플릿 함수와 동일한 이름의 함수 중복
for(int i=0; i<n; i++)
cout << (int)array[i] << '\t'; // array[i]를 int 타입으로 변환하여 정수 출력
cout << endl;
}
int main() {
int x[] = {1,2,3,4,5};
double d[5] = { 1.1, 2.2, 3.3, 4.4, 5.5 };
print(x, 5); // 템플릿으로부터 구체화한 함수 호출
print(d, 5); // 템플릿으로부터 구체화한 함수 호출
char c[5] = {1,2,3,4,5};
print(c, 5); // char 배열을 숫자로 출력하는 중복 함수 호출
}
템플릿 함수에 디폴트 매개 변수 사용
- 템플릿에서 함수 선언에 디폴트 매개 변수를 사용할 수 있다.
- 앞의 mcopy() 템플릿이 디폴트 매개 변수를 가지도록 수정하면 아래와 같다.
template <class T1, class T2>
void mcopy(T1 src[], T2 dest[], int n = 5) {
for (int i = 0; i < n; i++)
dest[i] = (T2)src[i];
}
728x90
'Programming Language > C++' 카테고리의 다른 글
[C++] 표준 템플릿 라이브러리(STL) (0) | 2023.12.20 |
---|---|
[C++] 제네릭 클래스 만들기 (1) | 2023.12.19 |
[C++] 템플릿 (0) | 2023.12.19 |
[C++] 추상 클래스 (1) | 2023.12.19 |
[C++] 가상 함수와 오버라이딩의 활용 사례 (1) | 2023.12.18 |