Quando "this" é capturado por um lambda, ele precisa ser usado explicitamente?

27

Os exemplos que eu descobri que a captura thisem um lambda a usam explicitamente; por exemplo:

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

Mas parece que também é possível usá-lo implicitamente; por exemplo:

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

Eu testei isso em g ++, e ele compilou.

Isso é C ++ padrão? (e, em caso afirmativo, qual versão) ou é alguma forma de extensão?

plugwash
fonte
11
As respostas estão corretas, mas há uma possível razão para o uso this->explícito, que é garantir que os valores capturados explicitamente sejam usados ​​explicitamente. Observe que [](){ calstage1done(); }isso não seria legal, porque thisnão seria capturado; mas quando capturando thisexplicitamente, é surpreendente para o corpo da função para aparecer de relance para não realmente usar o valor captado: [this](){ calstage1done(); }.
Kyle Strand
Eu posso ver isso, mas ao mesmo tempo parece horrivelmente detalhado para o que deveria ser uma tarefa simples.
plugwash 12/11/19
11
Lembro-me MSVC (talvez única 2015) também tendo problemas com a captura thise usá-lo em um lambda que também pode ser uma razão para usá-lo de forma explícita
Flamefire
@ plugwash: os desenvolvedores tendem a ser sempre preguiçosos e querem minimizar as coisas, e os designers de idiomas não são diferentes. No entanto, a verbosidade é frequentemente necessária para resolver a ambiguidade, e esse é o caso aqui.
Flater

Respostas:

25

É padrão e tem sido assim desde C ++ 11, quando foram adicionadas lambdas. De acordo com cppreference.com :

Para fins de pesquisa de nome, determinação do tipo e valor do thisponteiro e para acessar membros de classe não estáticos, o corpo do operador de chamada de função do tipo de fechamento é considerado no contexto da expressão 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
fonte
19

É completamente padrão e tem sido desde que as lambdas foram introduzidas no C ++ 11.

Você não precisa escrever this->lá.

Raças de leveza em órbita
fonte