2012-08-29 4 views
12

과부하 해결 중에 함수 개체가 일반 함수와 다르게 처리됩니까? 그렇다면 어떻게? 여기기능 개체가 과부하 해결에 어떻게 영향을 줍니까?

#include <iostream> 

namespace N 
{ 
    enum E { A, B }; 

    void bar(E mode) { std::cout << "N::bar\n"; } 
} 

template <typename... Args> 
void bar(Args&&... args) { std::cout << "global bar\n"; } 

int main() 
{ 
    bar(N::A); 
} 

출력은 "N : 바"이다

동등하게 호출 가능한 함수 객체 함수를 대체 여기서 I는 다음의 경우에 실행 된 코드의 의미를 변경. 지금까지는 매우 좋았습니다 : N :: bar는 ADL에 의해 발견되었습니다. N :: bar와 전역 막대가 정확히 일치합니다. N :: bar는 템플릿이 아니기 때문에 선호됩니다.

그러나 나는과 같이, 함수 객체로 글로벌 줄을 변경할 경우 :

#include <iostream> 

namespace N 
{ 
    enum E { A, B }; 

    void bar(E mode) { std::cout << "N::bar\n"; } 
} 

struct S 
{ 
    template <typename... Args> 
    void operator()(Args&&... args) { std::cout << "global bar\n"; } 
}; 
S bar; 

int main() 
{ 
    bar(N::A); 
} 

출력은 이제 "글로벌 바"입니다. 차이점은 무엇입니까?

답변

12

여기 중요한 비트는 조회가 이름 호출 이 함수 호출의 함수 인이라는 것을 결정하는 경우에만 실행된다는 것입니다. 두 번째 경우에 bar개체 인이고 함수가 아니므로 식 bar(N::A)은 함수 호출이 아니며 개체 baroperator()을 적용한 것입니다. 함수 호출이 아니기 때문에 ADL은 시작되지 않으며 N::bar은 고려되지 않습니다.

3.4.1/3

3.4.2에서 설명 된 함수 호출의 후위 표현으로 사용 적정 이름에 대한 조회. [주의 : (구문 분석하는 동안) 표현식이 함수 호출에 대한 후치식인지 결정하기 위해 일반적인 이름 조회 규칙이 적용됩니다. 3.4.2 [ADL]의 규칙은 표현식의 구문 해석에 영향을 미치지 않습니다.

그것을 보는 또 다른 방법은 ADL이 오버로드 기능의 세트에 새로운 기능을 추가 할 것을 통지하는 것입니다,하지만 두 번째 예에서 그러한 설정이 없습니다 : 조회 오브젝트와의 멤버를 찾습니다 개체가 호출됩니다.

+2

오늘 나는 David에게 감사 드렸다. – ildjarn

+0

나는 3.4의 노트를 생각하지 않는다.왜냐하면'bar' *는 함수 호출 표현식에서 후치 - 표현식이기 때문입니다 (피연산자로 함수를 가지지 않지만 결국 하나를 호출합니다!). 주석에 따르면 3.4.2는 "x (y)"의 구문상의 의미를 변경하지 않습니다. 함수 호출 인 경우 함수 호출을 무시하고 3.4.2로 결정합니다. –

+0

@ JohannesSchaub-litb : 정규 lookup은'bar'가 객체라는 것을 알게되고'bar (x)'는 그 인스턴스에 대해'operator() '의 적용을 나타냅니다. 연산자의 응용 프로그램은 함수 호출이지만 * 구성원 함수 * 호출이므로 ADL이 적용되지 않습니다. –

4

은 (다음과 같이 정의)

하자 X이 규정 조회 (3.4.1)에 의해 생성 된 조회 설정하고 Y가 인수 종속 조회에 의해 생성 된 조회 세트하자라고하는 3.4.2p3를 참조하십시오. X는

  • ...
  • 함수 나 함수 템플릿도이 선언이 포함되어있는 경우

는 Y가 비어 있습니다.

그러한 규칙이 없으면 ADL이 다른 기능을 오버로드 집합에 추가합니다. 사실, 13.3.1.1p1은 이것에 의존합니다. 하나는 피연산자가 클래스 객체를 나타내는 함수 호출 표현식이고 다른 하나는 피연산자가 하나 이상의 함수 또는 함수 템플리트를 나타내는 것입니다.

+0

+1 표준의 해당 부분을 검토 한 후에 제공 한 견적이 제가 인용 한 메모의 이유입니다. –

+0

@ david 오해하고 있습니다. –

관련 문제