2016-10-05 6 views
0

typedef/콜백 함수에 문제가 있습니다. 여기 C++ 해결되지 않은 오버로드 된 함수 유형

typedef void (*timer_cb_fn_t)(void); //defined in timer.h 

이 timer_start 함수의 정의는 timer.cpp에 정의되어

unsigned int TimClass:: timer_start(unsigned int interval, timer_cb_fn_t cb) 
{ 
//do stuff 
} 

dpl.h는 timer.h

내가 dpl.cpp 파일에서 타이머 함수를 호출하려고 포함 내가 invo입니다

void Dpl::receive_timeout(void) 
    { 
     receive_state = STATE_IDLE; 
    } 

으로 기능을 다시 전화 정의된다 기능 타이머는 다음 호출로 시작합니다.

unsigned int receive_timer = timer_start(TIMER_FRAME_TIME_MS, receive_timeout); 

g ++ 컴파일러는 다음 오류를 발생시킵니다.

./src/dpl/dpl.cc:138:107: error: no matching function for call to ‘TimClass::timer_start(unsigned int, <unresolved overloaded function type>)’ 
../dpl.cc:138:107: note: candidate is: 
../timer.h:256:16: note: unsigned int TimClass::timer_start(unsigned int, timer_cb_fn_t) 
../timer.h:256:16: note: no known conversion for argument 2 from ‘<unresolved overloaded function type>’ to ‘timer_cb_fn_t {aka void (*)()}’ 
make: *** [build/dpl.o] Error 1 

이 문제를 해결하는 방법을 알려주십시오.

+3

항상 내가 주석으로 게시하도록하겠습니다, A [mcve] –

+1

하지 답변을 게시하시기 바랍니다 : 당신이 C에서 함수 포인터를 사용할 수 없습니다 ++. 여전히 특정 상황에서 유용하지만, 템플릿/펑터와 그 사이의'std :: function'은 대부분의 유스 케이스를 더 잘 처리한다고 생각합니다. –

+0

C++의 차세대 언어 인 C++ + (제목에 지정된대로)를 모르십니까? :) – nosbor

답변

3

Dpl::receive_timeout 유형은 void (Dpl::*)(void)이며 암시적인 this 매개 변수를 사용합니다. 함수를 정적으로 만드십시오. (정적이 아닌 클래스 멤버를 사용하고있는 것 같기 때문에 이것을 할 수 있다고 생각하지 않습니다) 또는 펑터를 수락하고 람다/std::function<void(void)>을 전달하도록 타이머 정의를 변경하십시오.

정적 콜백 :

// function declaration 
class Dpl{ 
    // ... 
    static receive_timeout(void); 
    // ... 
}; 

// function definition 
void Dpl::receive_timeout(void) 
{ 
    receive_state = STATE_IDLE; 
} 

람다 :

template<typename T> 
unsigned int TimClass:: timer_start(unsigned int interval, T&& callback) 
{ 
//do stuff 
} 

std::function (참고 : 런타임시 많은 비용 인 유형 소거 사용)

unsigned int TimClass:: timer_start(unsigned int interval, std::function<void(void)> const& callback) 
{ 
//do stuff 
} 

그런데 , 멤버 함수의 주소를 가져 오려면 정규화 된 이름과을 사용해야합니다.:

&Dpl::receive_timeout 
+0

함수가 템플릿 화되어 있고 어떤 펑터를 받아들이면'std :: function'을 만들 이유가 없습니다. 람다를 직접 전달할 것입니다. 더 일반적인 것은'std :: function'을 받아 들여 람다 나 함수를 그것으로 전달하는 함수의 반대입니다. 일반적으로 템플리트를 피하거나 유형 삭제가 필요할 때이 작업을 수행합니다. –

+2

저는 인터페이스에 대한 두 가지 인기있는 대안이라고 말하고 싶습니다. 나는 분명히 할 것이다. – krzaq

+0

기술적으로 말해서이 기능은 무료 기능이어야합니다. 정적 메서드는 다른 호출 규칙을 가질 수 있습니다. 그래서 이것은 UB입니다. 하지만 호출 규칙이 달라지고 코드 가독성을 위해 정적 함수가 더 나은 플랫폼은 없습니다. –

관련 문제