강의/computer science

[ComputerScience] c++의 function overloading

하기싫지만어떡해해야지 2024. 10. 6. 17:09

이 게시글은

서울대학교 데이터사이언스대학원

조요한 교수님의

데이터사이언스 응용을 위한 컴퓨팅 강의를

학습을 위해 재구성하였습니다.


이번 시간에는 c++에서

함수를 다룰 수 있는 다양한 방법들과

function overloading에서 대해서

배운 내용을 정리해보려고한다

 

Default Arguments in Functions

 

 

우선 c++에서는 함수의 인자값를

default로 설정할 수 있다

 

함수를 호출 할 때

두 번째 인자값을 넘겨주면

넘겨준 값으로 들어가지만

아무것도 넘겨주지 않는다면

default로 설정해둔 2가 들어가게 된다

 

 

Function Overloading

C에서는 같은 함수의 이름을

여러 개 사용할 수 없었지만

c++은 가능하다

 

이런걸 function overloading이라고 한다

 

 

 

이름이 같은 함수들을

오른쪽과 같이 넘겨주는 parameters만

다르게 해줄 수 있다

 

 

그럼 이렇게 이름이 동일한 함수는

compiler는 어떻게 구분하나?

 

바로 name mangling이라는 기능을 사용한다

nane mangling이 무엇이냐면

컴파일러는 컴파일 과정에서

함수의 이름과 함수의 파라미터들을 보고

그 함수의 uniqu한 이름을 생성한다

 

한 마디로, 컴파일러는

함수의 이름만 보는게 아니고

함수가 넘겨주는 파라미터까지 같이 보고

새로운 이름을 자체적으로 만든다는 의미이다

ppt의 예시에서

void swap(int& a, int&b)가 있으면

__Z4swapRiS_와 같이

새로운 이름을 만들어준다

 

이러한 과정을 name mangling이라고 한다

따라서 함수의 이름은 같아도

파라미터 타입이 달라지면

컴파일러가 생성하는 name은

달라지기 때문에 구분이 가능한 것이다

 

 

Function Templates

그런데 이렇게 똑같은 함수를

data type만 바꿔서 여러 개

작성해주기도 귀찮다

 

그래서 함수를 한 개만 만든 다음

어떤 데이터 타입이 들어오든지

상관없게 만들어주자

 

그게 가능하게 하는 것을

function template이라고 한다

 

 

 

위에 

template <typename T>

라고 선언해줘서

generic한 타입을 T라고 사용할 것임을

선언해준다

 

그 다음 원래는

int, double같은 데이터 타입이 있었던 곳에

generic한 type인 T를 넣어주고

temp도 T 타입으로

선언을 해준다

 

 

이렇게 T로 선언한 함수를

사용하려면

mySwap 이름 뒤에

<int>라고 넣어주면

위에 선언했던

T temp는

자동으로 int타입의

변수가 되는 것이다

 

int뿐만이 아니고

double, string 등

다양한 데이터타입에

사용이 가능하다

 

 

compiler가 자동으로 추론할 수 있다면

int와 같은 data type을

안써도 된다고 한다

 

위의 예시의 경우

이미 위에서

int a, int b를 선언해주고

바로 다음 a와 b를

mySwap 함수에 넣어주고 있으므로

컴파일러가 자동으로 int임을

추론할 수 있다고 한다

 

하지만 데이터타입을

명확하게 써주는게

가독성 측면에서도 좋고

실수 방지에도 좋아

안전하다

 

 

하지만 compiler가 자동으로 추론을

할 수 없을 때는 반드시

data type을 명시해줘야한다

 

위의 경우 두 가지의 경우

모두 다 error가 발생한다

 

오른쪽의 경우

nullptr이 들어가는 것 자체는

문제가 없지만

data type이 없이 nullptr이 들어가면

컴파일러가 T의 데이터 타입이

무엇인지 추론이 불가능해진다

그래서 에러가 발생하는 것이다

 

 

 

위와같이 generic으로 정의한

mySwap함수를

한 번은 int로 한 번은 double로

두 번 호출을 해보자

 

프로그래머 입장에서는

똑같은 함수를 단순히

2번 호출했다고 생각할 수 있지만

실제 내부에서는 함수가 2개가

생성된다

 

mySwap int 버전이 1개가 생성되고

그 밑에는 double 버전이 1개가 더 생성되어

함수를 수행하게 된다

 

 

 

generic T로 선언한 함수에서

argument는 여러 개가 될 수 있다

 

그리고 T1과 T2는

다른 데이터타입을 가질 수 있다

 

다만 이럴 경우 위에

template <typename T1, typename T2>와 같이

반드시 명시해줘야한다

 

 

그렇다면 function template을 사용하는

대표적인 예시는 뭐가 있을까

 

바로 우리가 자주 쓰는

find 메소드이다

 

cpp reference에서

find method의 정의를 잘 보면

InputIt과 T의

generic한 type을 정의해주고

first와 last는 InputIt으로

찾는 value는 T로 정의해줬다

 

따라서 find 메소드를 쓸 때

first와 last가

iterator가 들어가면

자동으로 iterator로 변환이 되어

사용이 가능해지는 것이고

value도 마찬가지이다

 

 

함수들이 지금까지

프로그래머의 편의를 위해

어떻게 발전했는지를 정리한 장이다

 

제일 처음 기존에는

같은 이름의 함수는 사용이 안되었다가

두 번째에 

parameters만 다르면

같은 이름의 함수도 사용이 가능해졌다가

마지막으로는 function template을 사용해

다양한 데이터타입에 대한 함수를

한 개만 정의해도 되게 만들어줬다