나는 내 코드 전체에 마법 상자가 흩어져있는 것을 싫어합니다 … function <>에 전달되는 매개 변수와 완전히 다른 매개 변수가 설정되어 있더라도이 두 클래스가 기본적으로 함수 객체에 매핑되도록 정확히 어떻게 작동합니까? boost::bind
다른 호출 규칙에서도 작동합니다 (즉, 멤버 메서드는 __thiscall
VC하에 있지만 “일반”함수는 일반적으로 __cdecl
또는 __stdcall
C와 호환되어야하는 함수를 위한 것입니다.
답변
boost::function
operator()
올바른 서명을 가진 모든 것을 매개 변수로 바인딩 할 수 있으며, 바인딩 결과는 매개 변수로 호출 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_type
와 int
의 서명에서 추론 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); }
};
즉, 귀하의 경우 기능을 향상시키는 할당 :
- 유형을 인스턴스화합니다
function_impl_concrete<void(int), unspecified_type>
(물론 컴파일 시간) - 힙에 해당 유형의 새 개체를 만듭니다.
- 이 객체를 boost :: function의 f 멤버에 할당합니다.
함수 객체를 호출하면 해당 구현 객체의 가상 함수를 호출하여 원래 함수에 대한 호출을 지시합니다.
면책 조항 :이 설명의 이름은 의도적으로 구성되었습니다. 실제 인물이나 등장 인물과 닮은 점은 모두 알고 있습니다. 목적은 원리를 설명하는 것이 었습니다.