728x90

황기태 저자의 명품 C++ Programming 개정판을 읽고 학습한 내용을 정리한 포스트입니다!

https://search.shopping.naver.com/book/catalog/32436115747

 

C++ Programming : 네이버 도서

네이버 도서 상세정보를 제공합니다.

search.shopping.naver.com

 

하나의 제네릭 타입을 가진 경우

두 개의 매개 변수로 부터 큰 값 구하기
  • 두 수를 매개 변수로 받아 큰 값을 리턴하는 제네릭 함수 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