2013-11-26 7 views
5

과부하 기준 함수 :C++ nonconst const가 다음 코드에서

int foo(const int& f) //version 1 
{ 
    int g = f; 
    return int(foo(g)); // calls itself, turning into SO 
} 

int& foo(int& f) //version 2 
{ 
    f *= -1; 
    return f; 
} 

int main() 
{ 
    int f = 11; 
    cout << foo(f) << endl; 
    cout << foo(22) << endl; 
} 

제 COUT 인쇄 -11 예상; f는 lvalue이므로 foo의 두 번째 버전에 바인딩됩니다 (단, 첫 번째 버전에도 바인딩 할 수 있지만 두 번째 버전은 더 일치합니다).

foo의 두 번째 호출은 매개 변수로 rvalue를 사용하므로 foo의 유일한 실행 가능 버전이 첫 번째 호출입니다. 여태까지는 그런대로 잘됐다. foo의 첫 번째 버전에서는 두 번째 버전 (왼쪽 값)을 호출하고 foo의 두 번째 버전을 호출 한 후 복사본을 반환 할 수 있도록 매개 변수 복사본을 만들었습니다. 이것은 스택 오버플로가 될 것입니다. 여전히 foo의 첫 번째 버전이 호출됩니다.

누군가가 왜 이런 일이 발생했는지 설명해 주시겠습니까? 첫 번째 버전 foo 내의 g은 매개 변수로 전달 될 때 foo의 두 번째 버전에 바인딩 될 것으로 예상됩니다.

+3

첫 번째'foo'는 두 번째'foo'에 대해 어떻게 알 수 있습니까? –

답변

10

정말 간단합니다. 바로 그 시점에서 foofoo(const int& f)을 의미합니다. 두 번째 선택은 없습니다. 아직. 정의를 변경하십시오. 또는 그들을 분리하십시오 :

int foo(const int& f); 
int& foo(int& f); 

int main() 
{ 
    int f = 11; 
    cout << foo(f) << endl; 
    cout << foo(22) << endl; 
} 


int foo(const int& f) //version 1 
{ 
    int g = f; 
    return int(foo(g)); // calls itself, turning into SO 
} 

int& foo(int& f) //version 2 
{ 
    f *= -1; 
    return f; 
} 
+0

글쎄, 그게 쉬운 ... – user1019710

2

첫 번째 선언은 두 번째 선언의 존재에 대해 전혀 알지 못합니다. 이 시도 :

int foo(int& f); 
int foo(const int& f) //version 1 
{ 
    int g = f; 
    return int(foo(g)); // calls itself, turning into SO 
} 
1

를 컴파일러가 라인에 도달하면 :

int foo(const int& f); 
int& foo(int& f); 
:

return int(foo(g)) 

그것은 파일의 상단에 프로토 타입 선언을 추가하여 오버로드 버전 2에 대해 알고하지 않습니다

컴파일러는 버전 2의 존재에 대해 알게 될 것이고 전화 할 때 foo을 사용할 때 고려할 수 있습니다.