2011-01-23 4 views
1

아래 코드를 참조하십시오. drive()이고, driveporsche입니다. 그러나, drive()의 선언을 주석 처리하지 않으면, g ++는 매우 이상한 '드라이브'를 제공합니다.이 범위 오류에서 펑터를 만들려고 할 때 선언되지 않았습니다. 왜?펑터를 만들 때 친구 함수의 가시성

#include <functional> 

class car { 
    friend void drive(const car c); 
}; 

//void drive(const car c); 

int main() { 

    car porsche; 
    drive(porsche); 
    std::pointer_to_unary_function<car, void> functor(drive); 

    return 0; 
} 

UPDATE 1 : 내가 그러나 나는 그것이 첫 번째 템플릿 매개 변수 드라이브의 인수의 유형을 말 했는가, ADL에 관한 대답은 거의 satified입니다, 그것은이다 차 :

std::pointer_to_unary_function<car, void> functor(drive); 

업데이트 2 :

class car { 
    friend void drive(const car c); 
}; 

//void drive(const car c) { } 

int main() { 
    car porsche; 
    drive(porsche); 
    void (*f)(const car); 
    f = drive; 
    return 0; 
} 
:
OK, 여기에 우리가 펑과 기능 헤더가 필요하지 않습니다, 더 간단한 코드입니다

자, 왜 컴파일러가 drive ADL을 찾을 수 없는지 이해합니다. 이유는 위와 같지만이 코드는 템플릿에 의해 가려지지 않습니다.

+0

[명백한 템플릿 인스턴스화 : 이상한 "f가이 범위에서 선언되지 않았습니다."] (http://stackoverflow.com/questions/4775581/explicit-template-instantiation-weird-f-was-not-declared) -in-this-scope) –

+0

ADL은 인수 유형을 추론하는 것이 아니라 이름을 찾는 것입니다. 찰스의 대답은 정확합니다. –

+0

예, 해당 질문을 삭제하려고합니다. 여기에있는 코드가 훨씬 좋습니다. – Ali

답변

5

클래스의 규정되지 않은 ID를 사용하여 friend 함수를 선언하고 해당 함수가 다른 클래스의 멤버가 아닌 경우 가장 가까운 클래스가 아닌 함수가 아닌 프로토 타입 범위에서 함수의 이름을 지정합니다.

해당 기능이 이전에 선언되지 않은 경우 friend 선언은 해당 기능을 해당 범위에 표시하지 않습니다.

그러나이 함수는 인수 종속 검색에서 볼 수 있습니다.

표현식 drive(porsche);에서 porsche은 유형이 car이므로 ADL이 사용되고 친구 기능이 있습니다.

drive에는 인수가 없으므로 ADL이 수행되지 않습니다. 조회가 실패하므로 drive이라는 선언이 표시되지 않습니다.

+0

@Ali : 컴파일러가 '드라이브'를 찾을 수 있다고 생각하는 이유는 무엇입니까? '드라이브'에 대해 ADL을 수행하지 않으면 (함수 호출식이 아니기 때문에) ADL을 사용하지 않으면 '드라이브'에 대한 표시가 없습니다. . –

+0

그래, 나는 ADL이 무엇인지 더 많이 읽을 것이다. 나는 당신의 대답에서 인수 유형을 추론하는 것이 충분하다고 생각할 것입니다. – Ali

+0

@Ali : 귀하의 요지를 이해하지 못합니다. 템플릿에 대한 모든 인수를 지정하면 인수 공제가 필요하지 않거나 가능하지 않습니다. 문제는 'drive'라는 이름이 비 ADL 조회에서 보이지 않는다는 것입니다. –

0

친구가 함수를 선언하지 않아 존재하지 않는 전역 함수를 호출하려고하기 때문에.

+1

함수를 선언하지 않으면 어떻게하면 포르쉐를 운전할 수 있습니까? – Ali

+0

드라이브를 전역 함수로 사용하려는 경우 (일반적으로 사람들이하는 일은 클래스 멤버 함수 임에도 불구하고), 다음을 정의해야합니다. drive function. 그것을 정의하는 한가지 방법은 다음과 같다 : class drive {friend void drive (const car c) {여기에 뭔가 쓰기;}}; 그리고 그것을 정의하는 또 다른 방법은 전역 수준에있을 것이다 : void drive (const car c) {something something here;} 친구 공백 운전 (const car c)은 그 자체로 함수를 정의하지 않는다. 비슷한 함수가 존재한다면 그 클래스의 친구이다. – kynnysmatto

+2

친구 *는 *를 선언하지 않는다. 함수 : –