2014-04-30 7 views
1

std :: bind를 사용하여 variadic 함수의 첫 번째 매개 변수를 바인딩 한 다음 반환 된 펑터를 boost :: signals2 :: 신호의 connect() 함수에 전달하려고합니다. variadic 함수가 멤버 함수가 아닌 한 프로세스는 잘 작동합니다. 내가 ...이 템플릿 유형으로 채워집니다 "에 ... 통화에 대해 일치"가없는 상태 오류가 컴파일 할 때어떻게 variadic 멤버 함수를 functor에 바인딩 할 수 있습니까?

class test { 
public: 
    test() {} 

    void call_var_callback(string const& func, ...) { 
    va_list args; 
    va_start(args, func); 

    std::cout << "Calling variadic function: " << func << std::endl; 
    } 
}; 

test t; 

void register_callback2(std::map<string, boost::any>& sig_table, 
         string func, string event) { 

    auto event_entry = sig_table.find(event); 
    if (event_entry != sig_table.end()) { 

    if (event == "event1") { 
     auto sig = boost::any_cast<signal<void (void)>*>(sig_table["event1"]); 

     sig->connect(std::bind(&test::call_var_callback, &t, std::cref(func))); 
     //   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
    } 

    } else { 
    std::cout << "No such event exists!" << std::endl; 
    } 
} 

int main(void) { 

    // define events 
    signal<void (void)> event1; 
    signal<void (char const*)> event2; 
    signal<void (int, char const*)> event3; 

    // intialize event/signal lookup table 
    std::map<string, boost::any> sig_tbl; 
    sig_tbl["event1"] = &event1; 
    sig_tbl["event2"] = &event2; 
    sig_tbl["event3"] = &event3; 

    // connect the signals 
    register_callback2(sig_tbl, "func1", "event1"); 
    register_callback2(sig_tbl, "func2", "event2"); 
    register_callback2(sig_tbl, "func3", "event3"); 

    // call the signals 
    for (int i = 1000; i > 0; --i) { 
    (*boost::any_cast<signal<void (void)>*>(sig_tbl["event1"]))(); 
    (*boost::any_cast<signal<void (char const*)>*>(sig_tbl["event2"]))("0xBAAD"); 
    (*boost::any_cast<signal<void (int, char const*)>*>(sig_tbl["event3"]))(5, "0xBEEF"); 
    } 
} 

:이 내가 할 수있을 싶은 것이있다 바인딩 할 호출의 call_var_callback()의 ​​정의를 'test'객체의 범위 밖으로 이동하면 모든 것이 작동합니다. 그러나 실제 코드베이스에서는 바운드 함수가 상태를 유지하기 때문에 클래스의 멤버가되기 위해 바인딩 된 함수가 필요합니다.

귀하의 협조와 도움에 미리 감사드립니다.

+2

그럼 뭐가 문제 야? 관찰 된 정확한 오류 또는 원하지 않는 런타임 동작을 언급하십시오. 덧붙여서, 여러분의 예제에서 여러분은'register_callback2'의 끝 부분에서 파괴되는 지역 변수't'의 주소에 바인딩하고 있습니다. 이것은 신호가 발령 될 때 정의되지 않은 행동을합니다. – Oktalist

+0

의견에 감사드립니다. 나는 희망을 갖고 일을 좀 더 분명하게하기 위해 나의 질문을 편집했다. – maaronking

+0

_Precise_ 오류주십시오. – Oktalist

답변

1

멤버 함수를 바인딩 할 때 개체의 주소를 사용하지 않습니다. 당신의 코드에서 : 당신은

  • 는 객체 자체 또는
  • 를 전달할 수 있습니다 다음 &t가 잘못

    sig->connect(std::bind(&test::call_var_callback, &t, std::cref(func))); 
    

    , 그것은 일반 t

    bind 개체를 바인딩의 두 가지 방법을 지원해야한다

  • 개체 포인터 (원시 포인터 대신 공유 포인터는 물론)
+0

내 장난감 예제에서 실수. 나는 그것을 편집에서 고쳤다. 그 점을 지적 해 주셔서 감사합니다. – maaronking