2016-05-02 21 views
1

Ich bin fimilar mit std :: Funktion, aber ich bin ein Buch zu lesen, dass es einen Code wie folgt:std :: function Template Syntax

template<typename GameObject, typename Function> 
std::function<void(SceneNode&, sf::Time)> derivedAction(Function fn) 
{ 
    return [=](SceneNode& node, sf::Time dt) 
    { 
     assert(dynamic_cast<GameObject *>(&node) != nullptr); 

     fn(static_cast<GameObject *>(&node), dt) 
    } 
} 

dann das Buch Verwendung Vorlage wie folgt aus:

Command moveLeft;//command is a structure 
moveLeft.action//action is a std::function object 
= derivedAction<Aircraft>(AircraftMover(-playerSpeed, 0)); 
//derivedAction specify<Aircraft> ??? 

meine Fragen sind:

1-derivedAction muss ein Objekt von std :: function, ich habe Referenzen geprüft, aber ich habe diese Art von initialazation nicht mit {} gefunden, wie das funktioniert?

2-es ist kompliziert für mich, den Lambda-Ausdruck zu verstehen, und warum gibt es eine Rückkehr dafür?

ich bin ziemlich verwirrt über dieses Stückchen Code, würde jede explination

Antwort

1

std::function ist ein Wrapper um etwas zu erkennen ist, die aufgerufen werden können (das heißt, können Sie operator() auf sie verwenden). Das ist ein Zeiger auf eine Funktion mit der Klasse operator() Überladen oder Lambda-Ausdruck.

In Ihrem Fall ist derivedAction eine Templat-Funktion, einen einzelnen Parameter (von Templat-Namenstyp Function) zu akzeptieren und mit einer Funktion void Rückgabetyp Rückkehr und zwei Parameter akzeptieren - SceneNode& und sf::Time.

So, um Ihre Fragen zu beantworten.

1-derivedAction muss ein Objekt von std :: function sein, ich habe Referenzen überprüft, aber ich habe diese Art der Initialisierung mit {} nicht gefunden, wie das funktioniert?

Nein, derivedAction ist eine Funktion wie jede andere (d. H. int foo(){ return 0; }).

2-ist es kompliziert für mich, den Lambda-Ausdruck zu verstehen, und warum gibt es eine Rückkehr dafür?

Noch einmal, der Rückgabewert von derivedAction ist eine Funktion (oder rahter, etwas, das aufrufbar ist).

Wenn Sie eng mit dem Code von derivedAction betrachten, sehen Sie, dass es nur eine Funktion Function fn mit einigen Kontrollen wickelt.

+0

eine andere Frage: wenn Gameobject typenname vor Function typename war, und wir verwendeten dieselbe Syntax, wenn wir abgeleiteteAction aufrufen, hätten wir einen Kompilierungsfehler? – shayan

+0

so gibt die abgeleitete Funktion den gesamten Lambda-Ausdruck als eine std :: -Funktion zurück? – shayan

+1

@shayan Wenn Sie diese beiden 'type's wechseln würden, würde das keinen Compilerfehler in der Definition verursachen. Es würde jedoch einen Compiler-Fehler beim Aufruf von "derivedAction" erzeugen, weil [Template Argument Deduction] (http://en.cppreference.com/w/cpp/language/template_argument_deduction) fehlschlägt. – Zereges

1

Für Ihre erste Frage ist derivedAction eine Funktion, so dass Sie wie bei jeder anderen Funktion einen leeren Körper {} definieren können.

Wie für Ihre zweite Frage, die return ist die Rückkehr von derivedAction. Die Aufteilung des Lambda ist wie folgt:

  • [=] Weist alle referenzierten Variable zu erfassen, indem eine Kopie machen
  • (SceneNode& node, sf::Time dt) die Eingabeargumente der Lambda-Funktion
  • Im Körper des Lambda beschreibt, den Lambda- Funktion arbeitet auf Fn().Es wandelt node in einen anderen Typ um und ändert das Objekt node.

In Ihrem Beispiel ist fnAircraftMover(-playerSpeed, 0). playerSpeed ​​ist vom Typ SceneNode& und 0 ist vom Typ sf::Time. Der Rückgabetyp dieser Funktion ist void. Also, was all dies am Ende ist, ändern Sie die playerSpeed Sie füttern in es basierend auf dt. Hoffe das macht Sinn ..!

Verwandte Themen