2009-02-09 9 views
80

내 코드 전체에 마술 상자가 흩어져있는 것을 좋아하지 않습니다 ...이 두 클래스는 기본적으로 모든 함수가 함수 객체에 매핑 될 수 있도록 실제로 어떻게 작동합니까? <은 (멤버 방법이 "정상"기능은 일반적으로에 필요로하는 사람들을 위해 __cdecl 또는 __stdcall 있습니다 VC에서 __thiscall을하지만, 즉 그것은 심지어 다른 호출 규칙 작동 boost::bindboost :: function 및 boost :: bind 작동법

에 통과하는 하나의 메신저로 설정 완전히 다른 매개 변수가 있습니다> C와 호환 가능합니다.

+0

위보기 : http://stackoverflow.com/questions/112738/how-does-boost-bind-work-behind-the-scenes-in-general –

+1

사실이 질문은 바인딩과 기능에 관한 것입니다. –

+0

예 따라서 여전히 바인딩 할 수있는 방법에 대한 질문을 떠난다. void MyClass : DoSomething (std :: string str, int number) boost :: function bind (& MyClass :: DoSomething, instance, "Hello World", _1) –

답변

94

boost::functionoperator() 올바른 서명을 매개 변수로 바인딩하고 바인드 결과를 int 매개 변수로 호출 할 수 있으므로 function<void(int)>에 바인딩 할 수 있습니다.

이 작동하는 방법이다 (이 설명은 std::function에 대해 모두 적용) :

boost::bind(&klass::member, instance, 0, _1)return_typeintklass::member의 서명에서 추론이

struct unspecified_type 
{ 
    ... some members ... 
    return_type operator()(int i) const { return instance->*&klass::member(0, i); 
} 

같은 객체를 반환하고, 함수 포인터와 바운드 매개 변수는 실제로 개체에 저장되지만 중요하지는 않습니다.

이제 boost::function 어떤 유형 검사도하지 않습니다 : 그것은 당신이 템플릿 매개 변수에서 제공하는 모든 객체와 모든 서명을 취할 것이고, 당신의 서명에 따라 호출 할 수있는 객체를 생성하고 객체를 호출 할 것입니다. 불가능하다면 컴파일 오류입니다.

boost::function 실제로 이런 목적 :

template <class Sig> 
class function 
{ 
    function_impl<Sig>* f; 
public: 
    return_type operator()(argument_type arg0) const { return (*f)(arg0); } 
}; 

return_typeargument_typeSig가 추출되고, f 동적 힙에 할당된다. 크기가 다른 완전히 관련없는 개체를 허용하려면 boost::function에 바인딩해야합니다.

function_impl 그냥 추상 클래스

template <class Sig> 
class function_impl 
{ 
public: 
    virtual return_type operator()(argument_type arg0) const=0; 
}; 

모든 작업을 수행하는 클래스입니다, boost::function에서 파생 된 구체적인 클래스입니다.

  1. 가 (물론, 그 시간을 컴파일의) 유형 function_impl_concrete<void(int), unspecified_type>를 인스턴스화 : 당신이 당신의 경우에 의미 boost::function

    template <class Sig, class Object> 
    class function_impl_concrete : public function_impl<Sig> 
    { 
        Object o 
    public: 
        virtual return_type operator()(argument_type arg0) const=0 { return o(arg0); } 
    }; 
    

    에 할당 할 각 개체 유형에 대한 하나가, 할당 기능을 강화하기 위해

  2. :: 함수는 부스트 F 부재이 객체를 할당 힙
  3. 해당 유형의 새로운 객체를 생성

함수 개체를 호출하면 구현 개체의 가상 함수가 호출되어 원래 함수로 호출됩니다.

면책 조항 :이 설명의 이름은 의도적으로 작성된 것입니다. 진짜 사람이나 등장 인물과 닮았습니다 ... 당신도 알고 있습니다. 목적은 원리를 설명하기위한 것이 었습니다.

+0

struct unspecified_type의 내용 (즉, operator() 함수의 코드)은 boost :: bind에 대한 과거 인수에서 기본적으로 생성 된 것으로, 모든 조합과 인수의 개수를 허용하는 사례 기반의 경우입니까? –

+1

아니요, 모든 arities를 처리하는 operator()의 템플릿이 있습니다. (다른 템플릿 인자가 조합을 처리합니다) – jpalecek

+0

마지막 코드 블록에서 다음과 같습니다 :'arg0) const = 0 {return ...'... 전에는 그것을 보지 못했습니다. 하나의 작동하지 않는 예제가 포럼에서 C++ faq에 연결된 후속 메시지가 순수 가상 함수가 본문을 가질 수 있다고 설명했지만 구문 (clang 및 gcc)을 사용하여 컴파일 할 코드를 얻을 수 없습니다. –