2011-11-22 9 views
4

참조 : (가) 원본 또는 업데이트 [33.11] Can I convert a pointer-to-function to a void*?p가 함수 포인터 인 경우 p (..) 또는 (* p) (..)를 사용해야합니까?

#include "stdafx.h" 
#include <iostream> 

int f(char x, int y) { return x; } 
int g(char x, int y) { return y; } 

typedef int(*FunctPtr)(char,int); 

int callit(FunctPtr p, char x, int y) // original 
{ 
    return p(x, y); 
} 

int callitB(FunctPtr p, char x, int y) // updated 
{ 
    return (*p)(x, y); 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    FunctPtr p = g;     // original 
    std::cout << p('c', 'a') << std::endl; 

    FunctPtr pB = &g;     // updated 
    std::cout << (*pB)('c', 'a') << std::endl; 

    return 0; 
} 

질문> 방법, 권장되는 방법은? 두 방법 모두 VS2010으로 테스트했으며 각 결과가 올바른 결과를 인쇄합니다.

void baz() 
{ 
    FredMemFn p = &Fred::f; ← declare a member-function pointer 
    ... 
} 
+1

포인터 - 회원 기능은 ** 전혀 다른 주제 **입니다. 나는 [내 대답] (http://stackoverflow.com/q/8198062/596781)의 끝에 간단히 언급한다. –

+1

분명히'(******************** p)()'를 사용해야합니다! –

답변

6

함수 포인터를 역 참조하는 다른 함수 포인터를 얻을 : 나는 원래의 게시물에 다음 사용을 참조 않지만

감사드립니다. 그래서, 그냥 f(), 그렇지 않으면 당신은 코드를 난독 화하고 있습니다.

회원에 대한 포인터가 모두 다른 짐승입니다. 그들은 .* 또는 ->* 연산자를 사용해야합니다. 따라서 함수/memebers에 대한 원시 포인터 대신 std::function (또는 boost::function)을 사용해야하는 이유이기도합니다. 이것을 사용하는

+3

아마도 'std :: function'에는 상당한 오버 헤드가 있다고 생각할 수 있습니다. 따라서 위기 상황에서 직선적 인 PTMF가 바람직 할 수 있습니다. –

+0

@KerrekSB 최근 벤치 마크를 알고 있습니까? 나는 bechmark와 함께 빠른 대표자의 해킹 구현을 제공하는 코드 프로젝트에 관한 기사를 보았지만, 그 데이터는 오히려 오래된 IIRC이다. –

+1

@ TamásSzelei : 두려워하지는 않지만,'std :: function'은 기본적으로 가상 디스패치와 동적 할당을 필요로하는 타입 지우기를 내부적으로 사용하도록 디자인되어 있다는 것을 압니다. 근본적인 이유로 최적화 할 수 없다는 직감이 있습니다. 따라서 꽉 닫혀 있거나 기억 장소가 필요한 경우에는 지불 할 진정한 가격이있을 수 있습니다. 나는 또한 비교를보기 위해 매우 호기심이 많을 것이다! –

0

당신은 양식 중 하나를 사용할 수 있지만 (나에게) 가장 자연스러운 같습니다

p(x, y); 
6

모두 괜찮 :

p(); 
(*p)(); 

그러나 첫 번째 바람직하고, 그 때문에 functor 객체와 더 일관성이 있습니다. 내가 처음 구문을 사용 만하기 때문에 가능하게 된이이 함수 포인터로 호출 할 수 있습니다 이제

template<typename Functor> 
void f(Functor fun) 
{ 
    fun(); //uniform invocation - it doesn't matter what it is. 
} 

, 그리고 펑 객체 모두, 예를 들어, 당신은 같은 함수 템플릿을 작성할 수 있습니다.

이야기의 도덕은 : 균일 한 호출을 위해 노력한다. invocation-entity가 함수 포인터인지 함수 객체인지에 관계없이 호출 구문이 동일해야하는 방식으로 코드를 작성하십시오.

+0

'* p()'를 테스트했으며 VS2010이 'C2100 : 불법적 인 간접 지정'을보고합니다. – q0987

+0

@ q0987 : 예. 내가 틀렸어. 그건 허용되지 않습니다. 내 대답을 바로 잡았어. – Nawaz

1

표준은 사용하는 모든 형태를 허용하지만, 당신이 혼동 독자를 원하지 않는다면, 그것은 명시 적으로 일반적으로 최고입니다 : &f 함수의 주소를 취할하고 (*p)(x, y)이 호출 할 수 있습니다.

+0

나는이 곳을 오랫동안 들었다. – q0987

관련 문제