[디딤돌 C++] 59. 전역 템플릿 함수

이번에는 전역 템플릿 함수를 만들고 사용하는 방법을 살펴볼게요.

전역 템플릿 함수는 형식은 달라도 알고리즘이 같을 때 템플릿 함수를 정의하여 사용합니다. 그리고 일부 알고리즘이 다를 때 이 또한 템플릿 인자를 추가하여 만들 수 있습니다.

먼저 전역 템플릿 함수를 만드는 방법을 알아봅시다. 템플릿 함수는 template 키워드 뒤에 템플릿 형식 인자 목록을 < >내부에 표현합니다. 이 때 템플릿 형식 인자는 가상의 이름으로 정하여 함수 코드를 정의할 때 사용합니다.

template <typename [가상 타입명],…>

[리턴형식] 템플릿 함수명(입력인자리스트)

{

   [코드]

}

typename 대신 class 예약어를 사용할 수도 있습니다.

template <typename [가상 타입명],…>

[리턴형식] 템플릿 함수명(입력인자리스트)

{

   [코드]

}

n 개의 데이터 중에 최대값이 있는 메모리 주소를 찾는 전역 템플릿 함수를 만들어서 사용해 봅시다. 이를 위해 데이터 형식과 데이터를 비교하기 위한 알고리즘이 필요하겠죠. 여기에서는 비교 데이터 형식을 data, 비교 알고리즘을 compare 이름을 사용할게요.

template <typename data,typename compare>
data *get_max_pos(data *base, size_t n,compare com)
{
    size_t mi = 0;//최대값이 있는 인덱스를 0으로 초기 설정
    size_t index;
    for(index = 1; index<n; index++)
    {
        if(com(base[mi], base[index])<0) //index 요소가 더 크면
        {
            mi = index; //mi를 index로 변경
        }
    }
    return base + mi;//최대값의 위치 반환
}

이처럼 정의한 템플릿 함수를 사용하는 곳에서는 원소 형식에 관계없이 연속적인 메모리에 데이터를 보관하고 있을 때 비교 알고리즘을 구체적으로 정의하여 get_max_pos 전역 템플릿 함수를 호출하면 컴파일러에서는 사용하는 형식 인자에 맞게 get_max_pos 함수를 기계어 코드에 작성합니다. 물론 사용하는 형식이 다르면 컴파일러는 get_max_pos 함수를 여러 개를 기계어 코드에 작성합니다.

다음은 int 형식을 원소로 하는 배열에서 최대값이 있는 위치를 찾기 위해 전역 템플릿 함수 get_max_pos를 호출하는 코드입니다. 먼저 비교 알고리즘을 함수로 정의합니다.

int compare_int(int a,int b)
{
    return a-b;
}
int main()
{
    int arr[10]={5,3,29,56,34,22,9,17,8,4};
전역 템플릿 함수 get_max_pos를 호출하여 최대값의 위치를 찾습니다.
    int *mi = get_max_pos(arr,10,compare_int);
    for(int i = 0; i<10; i++)
    {
        cout<<arr[i]<<" ";
    }
    cout<<endl;
    cout<<"최대값:"<<*mi<<", 최대값 요소의 인덱스:"<<mi - arr<<endl;
    return 0;
}

이처럼 호출하여 사용하면 컴파일러에서는 템플릿 형식 인자 data를 int로 compare를 compare_int로 변환하여 기계어 코드를 작성하여 이를 호출하게 합니다.

다음은 Book의 ISBN이 최대(사전식 비교)인 도서 개체를 찾기 위해 전역 템플릿 함수 get_max_pos를 호출하는 예제 코드입니다.

int compare_isbn(Book *book1, Book *book2)
{
    string isbn1 = book1->GetISBN();
    string isbn2 = book2->GetISBN();
    return isbn1.compare(isbn2);
}

int main()
{
    Book *books[5];

    books[0] = new Book("1234","C언어");
    books[1] = new Book("7834","C++");
    books[2] = new Book("4534","알고리즘");
    books[3] = new Book("9934","자료구조");
    books[4] = new Book("1284","C#");
    Book **max_book = get_max_pos(books,5,compare_isbn);
    
    for(int i = 0; i<5; i++)
    {
        books[i]->View();
    }
    
    cout<<"최대값 요소의 인덱스:"<<max_book - books<<endl;
    (*max_book)->View();

    for(int i = 0; i<5;i++)
    {
        delete books[i];
    }
    return 0;
}

다음은 앞에서 설명했던 예제 코드입니다.

//ehalgorithm.h
#pragma once
template <typename data,typename compare>
data *get_max_pos(data *base, size_t n,compare com)
{
    size_t mi = 0;//최대값이 있는 인덱스를 0으로 초기 설정
    size_t index;
    for(index = 1; index<n; index++)
    {
        if(com(base[mi], base[index])<0) //index 요소가 더 크면
        {
            mi = index; //mi를 index로 변경
        }
    }
    return base + mi;//최대값의 위치 반환
}
//Boom.h
#pragma once
#include <iostream>
#include <ostream>
#include <string>
using namespace std;

class Book
{
    const string isbn;
    string title;
public:
    Book(string isbn,string title);
    string GetISBN()const;
    string GetTitle()const;
    void View()const;
};
//Book.cpp
#include "Book.h"

Book::Book(string isbn,string title):isbn(isbn)
{
    this->title = title;
}
string Book::GetISBN()const
{
    return isbn;
}
string Book::GetTitle()const
{
    return title;
}
void Book::View()const
{
    cout<<"ISBN:"<<isbn<<" 제목:"<<title<<endl;
}
//Program.cpp
//전역 템플릿 함수
#include "ehalgorithm.h"
#include "Book.h"

int compare_int(int a,int b)
{
    return a-b;
}
int compare_isbn(Book *book1, Book *book2)
{
    string isbn1 = book1->GetISBN();
    string isbn2 = book2->GetISBN();
    return isbn1.compare(isbn2);
}

int main()
{
    int arr[10]={5,3,29,56,34,22,9,17,8,4};
    int *mi = get_max_pos(arr,10,compare_int);
    for(int i = 0; i<10; i++)
    {
        cout<<arr[i]<<" ";
    }
    cout<<endl;
    cout<<"최대값:"<<*mi<<", 최대값 요소의 인덱스:"<<mi - arr<<endl;

    Book *books[5];
    books[0] = new Book("1234","C언어");
    books[1] = new Book("7834","C++");
    books[2] = new Book("4534","알고리즘");
    books[3] = new Book("9934","자료구조");
    books[4] = new Book("1284","C#");
    Book **max_book = get_max_pos(books,5,compare_isbn);
    
    for(int i = 0; i<5; i++)
    {
        books[i]->View();
    }
    
    cout<<"최대값 요소의 인덱스:"<<max_book - books<<endl;
    (*max_book)->View();

    for(int i = 0; i<5;i++)
    {
        delete books[i];
    }

    return 0;
}

▷ 실행 결과

5 3 29 56 34 22 9 17 8 4 
최대값:56, 최대값 요소의 인덱스:3
ISBN:1234 제목:C언어
ISBN:7834 제목:C++
ISBN:4534 제목:알고리즘
ISBN:9934 제목:자료구조
ISBN:1284 제목:C#
최대값 요소의 인덱스:3
ISBN:9934 제목:자료구조