Lambda é um dos recursos mais notáveis do C++ Moderno.
Se você ainda não sabe como utilizar lambda, veja antes esse artigo:
Neste artigo, você aprenderá cinco vantagens do Lambdas. E para esse artigo utilizaremos técnicas já informadas em artigos anteriores do cpp::daily, tais como:
Vamos começar.
O primeiro ponto pode parecer bastante óbvio, mas é sempre bom apreciar o fato de que, desde o C++ 11, podemos escrever um código mais compacto. Por exemplo, recentemente, encontrei alguns casos de C++03/C++0x com expressões de ligação e functores auxiliares predefinidos da STL. Dê uma olhada no código:
Veja execução do código no @Compiler Explorer e note o valor da saída.
Agora vamos escrever esse mesmo código com Lambda:
Não apenas temos uma sintaxe mais curta para o objeto de função anônima, mas podemos até mesmo reduzir uma instrução de inclusão (já que não há mais necessidade de <functional>
).
Em C++03, você tinha que criar funções ou functores que poderiam estar longe do lugar onde você os passava como objetos chamáveis.
Isso é difícil de mostrar em exemplos artificiais simples, mas você pode imaginar um grande arquivo de origem, com mais de mil linhas de código. A organização do código pode fazer com que os functores possam ser localizados em um lugar de um arquivo (por exemplo, no topo). Então, o uso de um functor poderia ser centenas de linhas adiante ou antes no código, se você quisesse ver a definição de um functor, você teria que navegar para um local completamente diferente no arquivo. Esse salto pode diminuir sua produtividade.
Lambdas melhoram não somente a localidade e legibilidade, mas também a parte de nomenclatura. Uma vez que lambdas são anônimas, não há necessidade de você selecionar o nome significativo para todas as suas pequenas funções ou functores.
Vamos dar uma olhada em um caso em que você gostaria de modificar uma operação de comparação padrão para std::sort .
Saída:
Como você pode ver, podemos capturar uma variável local e usá-la em todas as invocações do comparador binário. Esse comportamento não é possível com funções regulares (a menos que você use globais, é claro), mas também não é direto com tipos de functores personalizados. Lambdas o tornam muito natural e também muito conveniente de usar.
No exemplo, capturei o contador
por referência. Essa abordagem funciona, mas se seu lambda for executado de forma assíncrona ou em threads diferentes você precisará prestar atenção em problemas de oscilação e sincronização.
Este é um dos exemplos mais legais não apenas relacionado a lambdas, mas também a vários recursos importantes do C++ Moderno (disponível principalmente em C++17).
O exemplo acima é uma abordagem útil para construir um objeto que pode ser chamado com todas as sobrecargas possíveis para tipos de variantes em tempo real. O padrão sobrecarregado é conceitualmente equivalente à seguinte estrutura:
É possível escrever um lambda genérico compacto que funcione para todos os tipos mantidos na variante. Isso pode suportar polimorfismo de tempo de execução com std::variant e std::visit .
Esta técnica é uma alternativa ao polimorfismo de tempo de execução baseado em funções virtuais. Aqui podemos trabalhar com tipos não relacionados. Não há necessidade de uma classe base comum.
Você pode pensar que lambdas foram introduzidos no C++11 e isso é tudo, nada mudou. Mas não é verdade.
Aqui está a lista dos principais recursos relacionados aos lambdas que obtivemos com os padrões C++ recentes:
Capturar com inicializador - com esse recurso, você pode capturar não apenas variáveis existentes do escopo externo, mas também criar novas variáveis de estado para lambdas. Isso também permitiu capturar apenas tipos móveis.
constexpr lambdas - em C++17 seus lambdas podem funcionar em um contexto constexpr!
Além de algumas coisas menores e correções.
Por hoje é só, são pequenas doses diárias que farão sempre nos manter antenado com o C++ !
Então se inscreva nos nossos Cursos de C++ Moderno . Você aprender criar:
Acesse o endereço:
Esse artigo foi baseado no artigo do Bartek como modificações e tradução feitas por mim mesmo.