2010-02-02 7 views
2

이 코드 : 왜이 코드는`:: boost :: bind`를 사용하여 컴파일러 오류가 발생합니까?

#include <boost/signals.hpp> 
#include <boost/bind.hpp> 
#include <boost/mem_fn.hpp> 
#include <iostream> 

class Recorder : public ::boost::signals::trackable { 
public: 
    void signalled() { 
     const void *me = this; 
     ::std::cerr << "Recorder at " << me << " signalled!\n"; 
    } 
}; 

void signalled() 
{ 
    ::std::cerr << "Signalled!\n"; 
} 

int main(int argc, const char *argv[]) 
{ 
    ::boost::signal<void()> sig; 
    sig.connect(&signalled); 
    { 
     Recorder r; 
     sig.connect(::boost::bind(&Recorder::signalled, &r, _1)); 
     sig(); 
    } 
    sig(); 
    return 0; 
} 

이 컴파일러 오류를 생성 :

In file included from move_constructor.cpp:2: 
/usr/include/boost/bind.hpp: In instantiation of ‘boost::_bi::result_traits<boost::_bi::unspecified, void (Recorder::*)()>’: 
/usr/include/boost/bind/bind_template.hpp:15: instantiated from ‘boost::_bi::bind_t<boost::_bi::unspecified, void (Recorder::*)(), boost::_bi::list2<boost::_bi::value<Recorder*>, boost::arg<1> > >’ 
move_constructor.cpp:25: instantiated from here 
/usr/include/boost/bind.hpp:67: error: ‘void (Recorder::*)()’ is not a class, struct, or union type 
In file included from /usr/include/boost/function/detail/maybe_include.hpp:13, 
       from /usr/include/boost/function/function0.hpp:11, 
       from /usr/include/boost/signals/signal_template.hpp:38, 
       from /usr/include/boost/signals/signal0.hpp:24, 
       from /usr/include/boost/signal.hpp:19, 
       from /usr/include/boost/signals.hpp:9, 
       from move_constructor.cpp:1: 
/usr/include/boost/function/function_template.hpp: In static member function ‘static void boost::detail::function::void_function_obj_invoker0<FunctionObj, R>::invoke(boost::detail::function::function_buffer&) [with FunctionObj = boost::_bi::bind_t<boost::_bi::unspecified, void (Recorder::*)(), boost::_bi::list2<boost::_bi::value<Recorder*>, boost::arg<1> > >, R = void]’: 
/usr/include/boost/function/function_template.hpp:904: instantiated from ‘void boost::function0<R>::assign_to(Functor) [with Functor = boost::_bi::bind_t<boost::_bi::unspecified, void (Recorder::*)(), boost::_bi::list2<boost::_bi::value<Recorder*>, boost::arg<1> > >, R = void]’ 
/usr/include/boost/function/function_template.hpp:720: instantiated from ‘boost::function0<R>::function0(Functor, typename boost::enable_if_c<boost::type_traits::ice_not::value, int>::type) [with Functor = boost::_bi::bind_t<boost::_bi::unspecified, void (Recorder::*)(), boost::_bi::list2<boost::_bi::value<Recorder*>, boost::arg<1> > >, R = void]’ 
/usr/include/boost/function/function_template.hpp:1040: instantiated from ‘boost::function<R()>::function(Functor, typename boost::enable_if_c<boost::type_traits::ice_not::value, int>::type) [with Functor = boost::_bi::bind_t<boost::_bi::unspecified, void (Recorder::*)(), boost::_bi::list2<boost::_bi::value<Recorder*>, boost::arg<1> > >, R = void]’ 
/usr/include/boost/signals/slot.hpp:111: instantiated from ‘boost::slot<SlotFunction>::slot(const F&) [with F = boost::_bi::bind_t<boost::_bi::unspecified, void (Recorder::*)(), boost::_bi::list2<boost::_bi::value<Recorder*>, boost::arg<1> > >, SlotFunction = boost::function<void()>]’ 
move_constructor.cpp:25: instantiated from here 
/usr/include/boost/function/function_template.hpp:152: error: no match for call to ‘(boost::_bi::bind_t<boost::_bi::unspecified, void (Recorder::*)(), boost::_bi::list2<boost::_bi::value<Recorder*>, boost::arg<1> > >)()’ 

이 설치 페도라 11 부스트 1.37.0 패키지에 페도라 11 상자에 g ++ 4.4.1와 함께입니다.

이 코드는 완전히 내게 유익한 것처럼 보입니다. 여기서 무슨 일이 벌어지고 있는지 이해할 수 없으며 템플릿 확장과 관련된 오류의 미로는 매우 혼란 스럽습니다. 문제가 무엇인지 아는 사람이 있습니까?

답변

6
sig.connect(::boost::bind(&Recorder::signalled, &r, _1)); 

여기서 남은 _1 자리 표시 자란 무엇입니까? 그것은 불필요한 것이며 connect는 void -> void 기능을 기대합니다. 불필요한 자리 표시자를 제거하면 코드가 컴파일됩니다.

당신은 &Recorder::signalled 제공 - 유형 void Recorder::(void)의 멤버 함수는 제대로 void -> void로 변경하는 레코더 포인터를 결합하고 추가로는 자리 _1를 떠나 - 분명히 잘못된 것.

+0

전적으로 부스트를 많이 사용하지 않았습니다. 당신은 분명히 정확하고 지금은 약간 어리 석다. :-) 내가 생각한 것은 자리 표시 자 변수가 전달 된 변수와 어떻게 든 일치했기 때문에 각 변수에 대해 자리 표시 자 등이 필요했습니다. 나는 분명히 혼란 스러웠다. – Omnifarious

+1

@Omnifarious - 문제 없음 :). 자리 표시자는 매개 변수를 건너 뜁니다. 예를 들어 func'void Blah :: f (int x, int y, int z)'를 사용하면'bind (& Blah :: f, & b, & sx, _1, & sz)'할 수 있고'void int)'함수를 호출합니다. –

+0

내가 생각했던 것보다 훨씬 더 의미가 있습니다. :-) – Omnifarious

관련 문제