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?


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*
        };
    }
};

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.