boost::function
pozwala, aby wszystko, co ma operator()
właściwą sygnaturę, zostało powiązane jako parametr, a wynik powiązania można wywołać z parametrem int
, więc można go powiązać function<void(int)>
.
Oto jak to działa (ten opis dotyczy również std::function
):
boost::bind(&klass::member, instance, 0, _1)
zwraca obiekt taki jak ten
struct unspecified_type
{
... some members ...
return_type operator()(int i) const { return instance->*&klass::member(0, i);
}
gdzie return_type
i int
są wywnioskowane z podpisu klass::member
, a wskaźnik funkcji i powiązany parametr są w rzeczywistości przechowywane w obiekcie, ale to nie jest ważne
Teraz boost::function
nie wykonuje żadnego sprawdzenia typu: weźmie dowolny obiekt i każdy podpis, który podasz w parametrze szablonu i utworzy obiekt, który można wywołać zgodnie z Twoim podpisem i wywoła obiekt. Jeśli to niemożliwe, jest to błąd kompilacji.
boost::function
to właściwie taki obiekt:
template <class Sig>
class function
{
function_impl<Sig>* f;
public:
return_type operator()(argument_type arg0) const { return (*f)(arg0); }
};
gdzie return_type
i argument_type
są wyodrębniane z Sig
i f
jest dynamicznie przydzielane na stercie. Jest to konieczne, aby umożliwić powiązanie całkowicie niepowiązanych obiektów o różnych rozmiarach boost::function
.
function_impl
to tylko klasa abstrakcyjna
template <class Sig>
class function_impl
{
public:
virtual return_type operator()(argument_type arg0) const=0;
};
Klasa, która wykonuje całą pracę, jest konkretną klasą pochodną boost::function
. Istnieje po jednym dla każdego typu obiektu, do którego przypisujeszboost::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); }
};
Oznacza to w twoim przypadku przypisanie do funkcji boost:
- tworzy instancję typu
function_impl_concrete<void(int), unspecified_type>
(to oczywiście czas kompilacji)
- tworzy nowy obiekt tego typu na stercie
- przypisuje ten obiekt elementowi f funkcji boost :: function
Kiedy wywołujesz obiekt funkcji, wywołuje on funkcję wirtualną swojego obiektu implementacji, która skieruje wywołanie do twojej oryginalnej funkcji.
ZRZECZENIE SIĘ: Należy pamiętać, że nazwy w tym wyjaśnieniu są celowo wymyślone. Jakiekolwiek podobieństwo do prawdziwych osób lub postaci ... wiesz o tym. Celem było zilustrowanie zasad.