2012-09-21 8 views
7

Elementfunktionen haben einen impliziten this Zeigerparameter. Warum akzeptiert std::function diese Signatur dann, wo S eine einfache Klasse ist? (complete sample)Warum akzeptiert die Funktion std :: eine Referenz in der Signatur?

std::function<void(S &)> func = &S::foo; 

es aufrufen funktioniert auch, und unterscheidet Objekte:

S s1 = {5}; 
S s2 = {6}; 

func(s1); //prints 5 
func(s2); //prints 6 

Was würde ich normalerweise erwarten ist, dass es einen Zeiger benötigt, die auch funktioniert: (complete sample)

Warum funktioniert der erste, wenn ich einen Verweis in die Elementfunktion übergebe, wenn der implizite Parameter this ein Zeiger ist?

Antwort

3

std::function<SIG> kann aus vielen Dingen konstruiert werden, die sich wie Funktionen verhalten und sie in ein entsprechendes std::function Objekt konvertieren.

In diesem Fall void S::foo() verhält sich ähnlich wie eine Funktion void foo_x(S&) (wie in sie beide einen S benötigen, rufen und potenziell S ändern, nichts zurückkehrt). Folglich stellt std::function<void(S&)> einen Konstruktor zum Konvertieren der Elementfunktion in ein Funktionsobjekt bereit. I.e.

std::function<void(S &)> func = &S::foo; 

verwendet einen Konstruktor, so etwas wie std::function<void(S&)>(void(S::)()), etwas Gleichwertiges zu schaffen:

void foo_x(S & s) { return s.foo(); } 
std::function<void(S&)> func = foo_x; 

Ähnlich

std::function<void(S * const)> func = &S::foo; 

entspricht

void foo_x(S * const s) { return s->foo(); } 
std::function<void(S* const)> func = foo_x; 

durch ein Konstruktor wie std::function<void(S* const)>(void(S::)()).

+2

Das war eine sehr informative Lektüre, danke. Es macht viel mehr Sinn, wenn man bedenkt, dass "std :: function" unabhängig von rohen Funktionszeigern ist und die Macht hat, das zu tun, was sie möchte, um die Usability des Wrappings zu erhöhen. – chris

5

Weil std::function korrekt ausgelegt ist. Die Tatsache, dass this ein Zeiger ist, ist ein Unfall der Geschichte und ein Detail innerhalb der Member-Funktion. Die Tatsache sollte keinen Einfluss auf die Design-Entscheidungen der Benutzer der Funktion haben.

Die Designer von std::function entschieden zu Recht, Elementfunktionen zu akzeptieren, wenn der erste Parametertyp in der Signatur eine Referenz ist.

Verwandte Themen