• 카테고리

    질문 & 답변
  • 세부 분야

    프로그래밍 언어

  • 해결 여부

    해결됨

sum 함수 오버로드 질문

21.03.11 05:53 작성 조회수 190

3

강의 듣고 궁금해서 아래 와 같이 나열 하였는데 sum 에러가 발생합니다. 혹시 추가 설명 가능한가요?

 template<typename Any>

  Any sum(Any, Any);

  template<typename Any>

  Any sum(int, Any);

  template<typename Any>

  Any sum(Any, float);

  template<typename Any>

  Any sum(int, float);

  int main() {

  int a = 1, b = 2;

  float c = 3.14, d = 1.592;

  cout << sum(a, b) << "\n" << endl;

        //sum 에러

  cout << sum(a, c) << "\n" << endl;

      //sum 에러

  cout << sum(c, d) << "\n" << endl;

     //sum 에러

  cout << sum(b, d) << "\n" << endl;

      //sum 에러

  }

  template<typename Any>

  Any sum(Any a, Any b) {

  return a + b;

  }

  template<typename Any>

  Any sum(int a, Any b) {

  return a + b;

  }

  template<typename Any>

  Any sum(Any a, float b) {

  return a + b;

  }

  template<typename Any>

  Any sum(int a, float b) {

  return a + b;

  }

답변 2

·

답변을 작성해보세요.

3

Template은 변수의 데이터형 결정을 유보한다는 점에서 매력적이지만 주의해서 사용하여야 합니다.

자, 저희 잠깐만 복습의 시간을 가져볼까요?

바로 이전 강의인 '함수 오버로딩'에서 함수 오버로딩은 매혹적인 기능이지만,

사용할 수 없는 두 가지 경우에 대해서 살펴본 바 있습니다.

  1. 함수의 리턴형만 다를 경우
  2. 함수를 사용할 때, 두 개 이상의 함수에 대응되는 경우

혹시 어떠한 이유로 에러가 발생했는지 감이 잡히실까요?

하나씩 경우를 살펴보겠습니다.

ex1)의 경우

sum함수를 호출할 때 int형 매개변수 a와 b를 사용하고 있습니다.

자, 그렇다면 sum 함수 A, B, C, D 중 어떤 경우가 ex1가 대응될 수 있나요?

첫 번째로 A가 대응될 수 있습니다.

ex1의 경우에서 A의 템플릿 Any는 int형으로 대응될 것 입니다.

다음으로 B에도 대응될 수 있습니다.

B의 경우 int형 매개변수와 Any형 매개변수를 취하는데, 

ex1의 경우에서 템플릿 Any가 int에 대응되서 사용될 수 있겠지요?

따라서 ex1의 경우 대응되는 함수가 두개이기 때문에 에러가 발생합니다.

ex2)의 경우

ex2는 sum 함수를 호출할 때 int형 매개변수와 float형 매개변수를 사용하고 있습니다.

이번에는 B와 C에 대응될 수 있기에 에러가 발생합니다.

ex3)의 경우

ex3는 float과 float을 사용하고 있습니다.

이번에는 A와 C에 대응될 수 있기에 에러가 발생합니다.

ex4)의 경우

ex4는 ex2와 마찬가지로 int와 float을 사용하고 있습니다.

마찬가지로 B와 C에 대응될 수 있기에 에러가 발생합니다.

.

자, 저희 여기에서 만족하지 말고 에러를 해결해볼까요?

에러가 발생한 원인은 함수를 호출 할 때 대응되는 함수의 원형이 두개 이상이었기 때문입니다.

따라서 대응되는 경우를 하나로 일치시켜주면 해결할 수 있을 것 같습니다.

ex1은 int와 int를,

ex2와 ex4는 int와 float을,

ex3는 float과 float을 요구하고 있습니다.

함수의 오버로딩만을 사용한다면 아래와 같이 코딩할 수 있겠네요!

#include <iostream>
using namespace std;

int sum(int a, int b) {
    return a + b;
}

float sum(int a, float b) {
    return a + b;
}

float sum(float a, float b) {
    return a + b;
}

int main() {

    int a = 1, b = 2;
    float c = 3.14, d = 1.592;

    //ex1)
    cout << sum(a, b) << "\n" << endl;
    //ex2)
    cout << sum(a, c) << "\n" << endl;
    //ex3)
    cout << sum(c, d) << "\n" << endl;
    //ex4)
    cout << sum(b, d) << "\n" << endl;

    return 0;
}

함수의 템플릿까지 이용한다면 아래와 같이도 코딩할 수 있겠네요 :)

#include <iostream>
using namespace std;

//case A
template<typename Any>
Any sum(int a, Any b) {
    return a + b;
}

//case B
template<typename Any>
float sum(float a, Any b) {
    return a + b;
}

int main() {
    
    int a = 1, b = 2;
    float c = 3.14, d = 1.592;

    //ex1)
    cout << sum(a, b) << "\n" << endl;
    //ex2)
    cout << sum(a, c) << "\n" << endl;
    //ex3)
    cout << sum(c, d) << "\n" << endl;
    //ex4)
    cout << sum(b, d) << "\n" << endl;

    return 0;
}

이 경우에서 case A와 case B의 return형에 주목해봅시다.

case A의 경우에는 Any의 타입이 float이냐 int냐에 따라,

return형 역시 float 혹은 int로 바뀌어야 합니다.

따라서 함수의 데이터형을 선언할 때 Any로 선언한 것을 확인할 수 있습니다.

반면에 case B의 경우 이미 float형 인자를 받고 있기 때문에,

return 역시 항상 float형으로 해주면 되겠죠?

물론 c++에서는 int형과 float형의 경우 자동으로 데이터형 변환이 발생하기 때문에,

이렇게 리턴형을 맞춰주는 과정이 없더라도 표면적으로 보이는 에러는 발생하지 않겠지만

float형에서 int형으로 형변환이 발생할 때,

소수점부의 소실이 있을 수 있을 겁니다.

혹시 이해가 되셨을까요?

dpkim2017님의 프로필

dpkim2017

질문자

2021.03.12

이해가 잘되었습니다. 자세한 설명을 해주셔서 감사합니다.  형변환 발생으로 소수점이 소실 되는 부분역시 직접 테스트 해보았습니다. 

함수 오버로딩에서 사용할수 없는 두가지 경우가 정말 중요하네요.

  1. 함수의 리턴형만 다를 경우
  2. 함수를 사용할 때, 두 개 이상의 함수에 대응되는 경우  

강의에 열정적으로 임해주셔서 정말 뿌듯합니다 :)
완강까지 화이팅하시길 바랍니다!!

0

답변에 사용될 코드입니다.

질문자 님께서 올려주신 코드와 동일하니 주석을 확인해주시면 될 것 같습니다 :)

#include <iostream>
using namespace std;

//A
template<typename Any>
Any sum(Any a, Any b) {
    return a + b;
}

//B
template<typename Any>
Any sum(int a, Any b) {
    return a + b;
}

//C
template<typename Any>
Any sum(Any a, float b) {
    return a + b;
}

//D
template<typename Any>
Any sum(int a, float b) {
    return a + b;
}

int main() {
    
    int a = 1, b = 2;
    float c = 3.14, d = 1.592;

    //ex1)
    cout << sum(a, b) << "\n" << endl;
    //ex2)
    cout << sum(a, c) << "\n" << endl;
    //ex3)
    cout << sum(c, d) << "\n" << endl;
    //ex4)
    cout << sum(b, d) << "\n" << endl;

    return 0;
}