boost :: function 및 boost :: bind 작동 방법


83

나는 내 코드 전체에 마법 상자가 흩어져있는 것을 싫어합니다 ... function <>에 전달되는 매개 변수와 완전히 다른 매개 변수가 설정되어 있더라도이 두 클래스가 기본적으로 함수 객체에 매핑되도록 정확히 어떻게 작동합니까? boost::bind

다른 호출 규칙에서도 작동합니다 (즉, 멤버 메서드는 __thiscallVC하에 있지만 "일반"함수는 일반적으로 __cdecl또는 __stdcallC와 호환되어야하는 함수를 위한 것입니다.



1
이 질문은 바인드와 기능에 관한 것입니다.
1800 INFORMATION

예, 따라서 bind (& MyClass :: DoSomething, instance, "Hello를 통해 boost :: function <void (int)> 맵 void MyClass : DoSomething (std :: string str, int number)를 바인딩 할 수있는 방법에 대한 질문이 여전히 남아 있습니다. World ", _1)
Fire Lancer

2
20,000 번의 성소 방문이 부스트 첫 페이지 에 있어야 합니다!
unixman83 2011

답변:


96

boost::functionoperator()올바른 서명을 가진 모든 것을 매개 변수로 바인딩 할 수 있으며, 바인딩 결과는 매개 변수로 호출 int될 수 있으므로에 바인딩 될 수 있습니다 function<void(int)>.

이것이 작동하는 방식입니다 (이 설명은에도 동일하게 적용됩니다 std::function).

boost::bind(&klass::member, instance, 0, _1) 다음과 같은 객체를 반환합니다.

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

어디 return_typeint의 서명에서 추론 klass::member하고, 함수 포인터와 바인딩 매개 변수는 실제로 객체에 저장됩니다,하지만 그건 중요하지 않아

이제 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_type과은 argument_type으로부터 추출 Sig하고, f동적 힙에 할당된다. 크기가 다른 완전히 관련이없는 객체를 boost::function.

function_impl 추상 클래스입니다

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

모든 작업을 수행하는 클래스는 boost::function. 할당 한 각 유형의 개체에 대해 하나씩 있습니다.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); }
};

즉, 귀하의 경우 기능을 향상시키는 할당 :

  1. 유형을 인스턴스화합니다 function_impl_concrete<void(int), unspecified_type>(물론 컴파일 시간)
  2. 힙에 해당 유형의 새 개체를 만듭니다.
  3. 이 객체를 boost :: function의 f 멤버에 할당합니다.

함수 객체를 호출하면 해당 구현 객체의 가상 함수를 호출하여 원래 함수에 대한 호출을 지시합니다.

면책 조항 :이 설명의 이름은 의도적으로 구성되었습니다. 실제 인물이나 등장 인물과 닮은 점은 모두 알고 있습니다. 목적은 원리를 설명하는 것이 었습니다.


그래서 struct unspecified_type (즉, operator () 함수의 코드)의 내용은 기본적으로 인수의 조합과 수를 허용하기 위해 케이스별로 boost :: bind 인수에서 생성됩니까?
Fire Lancer

1
아니요, 모든 인수를 처리하는 operator () 템플릿이 있습니다 (그리고 다른 템플릿 인수가 조합을 처리 함)
jpalecek

마지막 코드 블록에서 다음과 같이 읽습니다. arg0) const=0 { return...... 전에는 본 적이 없습니다. 순수한 가상 함수가 본문을 가질 수 있다고 설명하는 후속 메시지가 C ++ FAQ에 링크 된 포럼에서 작동하지 않는 예제를 찾았지만 그런 구문을 사용하여 컴파일 할 코드를 얻을 수 없습니다 (clang & gcc).
Brian Vandenberg 2013 년

나는 내 질문을 약간 명확히해야한다. 순수한 가상은 =0;나중에 주어질 본문으로 선언 될 때 본문에 주어질 수있다 (예, void Base::Blah() { /* ... */ }) ... 위에서 사용 된 표기법에 대해 구체적으로 묻고있다. 오타 일 뿐인 것 같아요.
Brian Vandenberg

@BrianVandenberg : 꽤 무의미하지만 표준 준수라고 생각합니다.
Mooing Duck 2014 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.