2011-08-03 7 views
0

나는 템플릿에서 상속의 중간 클래스 다음의 클래스 구조를 가지고 :부스트 :: 기능

#include <boost/function.hpp> 
#include <boost/bind.hpp> 

template<class T> 
struct Base { 
    typedef 
     boost::function<void (T*,int)> 
    callback_t; 

    callback_t m_callback; 

    Base(callback_t cb): 
     m_callback(cb) 
    {} 
    virtual ~Base() 
    {} 

    void handleError(int error_code) { 
     m_callback(this,error_code); 
    } 
}; 

struct Derived: public Base<Derived> { 
    Derived(Base<Derived>::callback_t cb): 
     Base<Derived>(cb) 
    {} 
    ~Derived() 
    {} 
}; 

struct Worker { 
    Derived m_o; 

    void myErrorHandler(Derived* o,int error_code) 
    {} 

    Worker(void): 
     m_o(boost::bind(&Worker::myErrorHandler,this,_1,_2)) 
    {} 
}; 

int main(int argc,const char** argv) 
{ 
    Worker m; 
    return(0); 
} 

목적은 노동자myErrorHandler() 동의하는 것입니다 임의의 정수 값과 함께 콜백을 생성 한 객체 진실은 말해서, 이것은 asio 콜백 핸들러의 간소화 버전이지만 간결함을 위해 asio를 제거했습니다.

컴파일러에 대해 불평 * 표시 형식 정의 ... callback_t * 템플릿, 말하는 내부 : 나는 callback_t의 정의에 유형 이름을 배치하여 사소한 힌트를 시도했지만, 아무것도이 문제가 과거 얻을 수 없습니다

../src/templates.cpp:13: error: a call to a constructor cannot appear in a constant-expression 
../src/templates.cpp:13: error: template argument 1 is invalid 

.

결국 3 클래스에서 파생 클래스 인스턴스처럼 보이는 1 ~ 많은 객체를 가질 수 있기를 바라고 각각은 Worker에서 콜백을 얻습니다. 오브젝트가 ctor/dtor을 수행하고 콜백을 구성 할 수 있도록 템플릿이 파생 클래스의 기본 클래스가되기를 원합니다.

callback_t에 대한 내 정의에서 뭔가가 누락 되었습니까?

*** 편집 업데이트 :

위의 코드가 컴파일됩니다. 많은 제안에 감사드립니다.

위의 코드에서 asio가 완전히 제거 된 경우에도 boost :: asio 태그를 추가했습니다. 템플릿/클래스는 자체 속성을 숨기고 관리 할 수있는 asio 타이머 래퍼를 모델링합니다. 내 프로토콜 완료 핸들러 (다중 상태 타이머를 가질 수 있음)는 읽기가 조금 더 쉬우 며 타이머 코드가 동일하지만 지금까지 복사/붙여 넣기를 수행하고 공통 클래스로 리팩터링하고 상속됩니다.

답변

0

여기에 typename이 필요하지 않습니다. T은 유형으로 알려져 있습니다. 또한 function 인수의 일부로 인수 이름을 사용할 수 없습니다. 그래서 그것은 단지 boost::function<void(T*, int)>이어야합니다.

그리고 아마도 typenameDerived(Base<Derived>::callback_t cb)에 필요합니다.

+0

정보 주셔서 감사합니다. 필자는 제안 된 편집 내용을 추가하고 내 자신을 추가했습니다. 이제 컴파일됩니다. 많은 감사합니다! –

0

먼저 언급했듯이 - 라인 7의 typename은 잘못되었습니다. 그러나 이러한 문맥에서 매개 변수의 이름을 함수 인수로 지정할 수 있으므로 error_code이 거기에 머무를 수 있습니다. 더 이상 typenames이 필요하지 않습니다.

둘째, 비 정적 멤버 함수 포인터를 바인딩하는 boost::bind의 두 번째 인수는 함수를 호출해야하는 개체에 대한 포인터 여야합니다. 두 번째 매개 변수로 this을 사용하면 도움이 될 것입니다. 논리적 의미에서 이것이 의도 된 것인지 완전히 명확하지는 않습니다.

+0

정보 주셔서 감사합니다. 나는 편집을했고, 내 것을 추가했다. –

+0

@zap이 답변으로 문제가 해결되면 옆에있는 체크 표시를 클릭하여 답변을 수락하십시오. –