Lorsque «ceci» est capturé par un lambda, doit-il être utilisé explicitement?

27

Les exemples que j'ai trouvés que la capture thisdans un lambda l'utilisent explicitement; par exemple:

capturecomplete = [this](){this->calstage1done();};

Mais il semble qu'il soit également possible de l'utiliser implicitement; par exemple:

capturecomplete = [this](){calstage1done();};

J'ai testé cela en g ++, et il a compilé.

Est-ce du C ++ standard? (et si oui, quelle version), ou s'agit-il d'une forme d'extension?

plugwash
la source
1
Les réponses sont correctes, mais il existe une raison possible d'utiliser this->explicitement, qui est de s'assurer que les valeurs explicitement capturées sont utilisées explicitement. Notez que [](){ calstage1done(); }ce ne serait pas légal, car thisne serait pas capturé; mais lors de la capture thisexplicitement, il est surprenant pour le corps de la fonction semble un coup d' oeil de ne pas utiliser réellement la valeur capturée: [this](){ calstage1done(); }.
Kyle Strand
Je peux en quelque sorte voir cela, mais en même temps, cela semble horriblement verbeux pour ce qui devrait être une tâche simple.
plugwash
1
Je me souviens que MSVC (peut-être seulement en 2015) avait également des problèmes avec sa capture thiset son utilisation dans un lambda, ce qui pourrait également être une raison de l'utiliser explicitement
Flamefire
@plugwash: Les développeurs ont tendance à être toujours paresseux et à minimiser les choses, et les concepteurs de langage ne sont pas différents. Cependant, la verbosité est souvent requise pour résoudre l'ambiguïté, et c'est le cas ici.
Flater

Réponses:

25

C'est standard et c'est le cas depuis C ++ 11 lorsque les lambdas ont été ajoutés. Selon cppreference.com :

Aux fins de la recherche de nom, de la détermination du type et de la valeur du thispointeur et de l'accès aux membres de classe non statiques, le corps de l'opérateur d'appel de fonction du type de fermeture est considéré dans le contexte de l'expression lambda.

struct X {
    int x, y;
    int operator()(int);
    void f()
    {
        // the context of the following lambda is the member function X::f
        [=]()->int
        {
            return operator()(this->x + y); // X::operator()(this->x + (*this).y)
                                            // this has type X*
        };
    }
};
Ayxan
la source
19

C'est tout à fait standard et ce depuis que lambdas a été introduit en C ++ 11.

Vous n'avez pas besoin d' this->y écrire .

Courses de légèreté en orbite
la source