web-dev-qa-db-fra.com

C ++ lambda capture cette capture vs par référence

Si j'ai besoin de générer un lambda qui appelle une fonction membre, dois-je capturer par référence ou capturer "ceci"? Ma compréhension est que "&" ne capture que les variables utilisées, mais "ceci" capture toutes les variables membres. Il vaut donc mieux utiliser '&'?

class MyClass {
  public:
    int mFunc() {
      // accesses member variables
    }

    std::function<int()> get() {
      //return [this] () { return this->mFunc(); };
      //  or
      //return [&] () { return this->mFunc(); };
    }

  private:
    // member variables
}
14
vikky.rk

Pour l'exemple spécifique que vous avez fourni, la capture par this est ce que vous voulez. Conceptuellement, la capture de this par référence n'a pas beaucoup de sens, puisque vous ne pouvez pas modifier la valeur de this, vous ne pouvez l'utiliser que comme pointeur pour accéder aux membres du ou pour obtenir l'adresse de l'instance de classe. Dans votre fonction lambda, si vous accédez à des choses qui utilisent implicitement le pointeur this (par exemple, vous appelez une fonction membre ou accédez à une variable membre sans utiliser explicitement this), le compilateur la traite comme si vous avait utilisé this de toute façon. Vous pouvez également répertorier plusieurs captures, donc si vous souhaitez capturer à la fois des membres et des variables locales, vous pouvez choisir indépendamment de les capturer par référence ou par valeur. L'article suivant devrait vous donner une bonne connaissance des lambdas et des captures:

https://crascit.com/2015/03/01/lambdas-for-lunch/

De plus, votre exemple utilise std::function comme type de retour par lequel le lambda est renvoyé à l'appelant. Soit conscient que std::function n'est pas toujours aussi bon marché que vous ne le pensez, donc si vous pouvez utiliser un lambda directement plutôt que de devoir l'envelopper dans un std::function, il sera probablement plus efficace. L'article suivant, bien qu'il ne soit pas directement lié à votre question initiale, peut néanmoins vous fournir des informations utiles concernant les lambdas et std::function (voir la section Une autre façon de stocker l'objet fonction , mais l'article en général peut être intéressant):

https://crascit.com/2015/06/03/on-leaving-scope-part-2/

15
Craig Scott

Ici est une bonne explication de ce que &, this et les autres indiquent quand ils sont utilisés dans la liste de capture.

Dans votre cas, en supposant que tout ce que vous avez à faire est d'appeler une fonction membre de l'instance réellement référencée par le this de la méthode en cours d'exécution, mettez this dans votre capture la liste devrait suffire.

6
skypjack

La capture this et la capture par référence sont deux concepts orthogonaux. Vous pouvez en utiliser un, les deux ou aucun. Il n'est pas logique de capturer this par référence, mais vous pouvez capturer d'autres variables par référence tout en capturant this par valeur.

2
R Sahu