• 카테고리

    질문 & 답변
  • 세부 분야

    프로그래밍 언어

  • 해결 여부

    미해결

함수 오버로딩시 매개변수가 const 일경우

21.02.05 18:56 작성 조회수 611

0

매개변수가 참조나 포인터일때 const 의 유무로도 함수오버로딩이 가능한 것으로 알고 있는데 

void    function(int *t_array, int length, void (*fptr)(int &val))
{
    for (int i = 0; i < length; i++)
        fptr(t_array[i]);
}


void    function(int *t_array, int length, void (*fptr)(const int &val))
{
    for (int i = 0; i < length; i++)
        fptr(t_array[i]);
}

위와같이 함수 포인터를 사용해서도 구분이 가능하더라고요.

그런데 함수포인터로 넘겨줄 함수가 아래와 같이 오버로딩이 되어있을때 

void print( int const & x ) { std::cout << x << std::endl; return; }

void print( int  & x ) { std::cout << x << std::endl; return; }

candidate function 에러가 발생하더라고요

print 함수중 하나만 주석을하고 컴파일을하면 에러가 발생하던데 차이점을 잘 모르겠습니다;; 

답변 2

·

답변을 작성해보세요.

2

안소님의 프로필

안소

2021.02.06

아 "레퍼런스나 포인터일 때"에 붙은 const는 오버로드 기준이 되는게 맞습니다. 앞에서 언급해주신 이 부분을 제가 빠뜨리고 이해했네요! (삭제하진 않겠습니다. 앞 답변은 그냥 스킵해주세요 ㅠㅠ)   

명쾌하게 답변을 드리기엔 저도 잘 모르겠고 굉장히 헷갈려서.. 도움이 못되 죄송하지만 ㅠ 

이렇게 타입을 명확하게 하여 넘기면 문제가 없더라구요. fptr1에는 void print(int& x) 의 주소가 들어갔고, fptr2은 void print(const int& x) 의 주소가 들어가게 되었습니다. 

4개의 함수 중 하나만 주석 처리 한다던가 위 처럼 타입을 명확히 결정하여 넘겼을 땐 문제가 없었던걸로 보아 

print도 여러개고 function도 여러개인 상태라는 것에 더불어

const int & 도 int &도 둘 다 L-value의 int를 받을 수 있다보니, 두 매개변수 함수 포인터 둘 다 L-value의 int 를 파라미터로 받는 함수를 호출할 수 있다는 의미가 되므로 어떤걸 기준으로 어떻게 매칭시켜야 하는지 모호해 하는게 아닌가 싶습니다. 저도 정확한 이유는 잘 모르겠습니다ㅠ

2

안소님의 프로필

안소

2021.02.06

안녕하세요.

const 유무가 오버로딩 기준이 될 때는 int func () const 이런 것 처럼 함수 자체의 뒤에 const가 붙었냐 안붙었냐일 때의 얘기입니다. (const 가 뒤에 붙은 멤버함수는 const 객체만이 호출할 수 있으므로 오버로딩 기준이 됩니다.)

const int a 이런 매개변수의 const 는 오버로딩 기준이 되지 않습니다.  

참조나 포인터에 붙은 const 

출처는 마이크로소프트의 함수 오버로드 문서입니다. 매개변수에 붙은 const는 오버로딩의 기준이 되지 않으며 동일하게 간주된다고 말하고 있습니다. 아래 줄은 멤버함수 뒤에 붙은 const 같은 경우, 이렇게 "함수 전체"에 작용하는 const의 경우엔 오버로드가 된다고 얘기하는 것입니다.!

저는 위와 같이 print함수던 function함수던 둘 중 하나를 주석처리 해야 에러가 발생하지 않았는데 하나만 주석 처리하면 에러가 발생하셨다고 하셔서 의아합니다. main 함수에서 진행하신 코드도 덧붙여 주셨으면 좋았을 것 같습니다!

우선 제가 진행한 코드를 상황을 바탕으로 말씀을 드리자면

4개의 함수를 전부 주석처리 안했을 떄 모습입니다.

void (*fptr)(const int &val) 매개 변수에서도 print를 받을 수  있고, void (*fptr)(int& val) 매개 변수에서도 print를 받을 수 있기 때문에 둘 중 어떤 function으로 해야할지 모르겠다는 에러입니다. 즉, 넘겨지는 print 파라미터가 두 function 함수 모두에서 받을 수 있어 인수 목록과 일치하기 때문에 오버로딩 하지 못한다는 에러와도 같습니다. 

void (*fptr)(const int &val) 매개 변수에서도, void (*fptr)(int& val) 매개 변수에서도 print를 받을 수 있습니다. 그러므로 오버로딩의 기준이 되지 않습니다. 

아래 예시를 보시면 이해가 되실 것 같습니다. 

 

실행시키면 이와 같은 에러가 발생합니다.

print(const int x) 와 print(int x ) 를 동일한 것으로 간주하기 때문입니다.