Duas das coisas que mais me agradaram no C++ atual são: a inferência de tipo e as expressões lambda (ou simplesmente lambda).
Neste post, quero focar em 5 pontos interessantes sobre estes assuntos. São eles:
1. O que é um lambda?
2. Lambda e Functor, qual a relação entre eles?
3. Como funciona a inferência feita em um lambda?
4. Lista de captura de um lambda
5. Legibilidade interessante
Muito resumidamente, o cálculo lambda (lambda calculus) é uma representação computacional de uma função matemática.
Ex λ: (x, y) -> 2 * x + y
No C++, o lambda é uma função com lista de captura, parâmetros e um retorno (que pode ser void).
A implementação de um lambda é a mesma implementação de um functor! Ou seja, o compilador mapeia/transforma um lambda em um functor equivalente.
O lambda tem: lista de captura, função recebendo parâmetros e um retorno
O functor tem: constructor, operador () recebendo parâmetros e um retorno
O lambda é uma maneira interessante para definir um functor anônimo.
Os dois vão virar código inline, mas qual tem a sintaxe mais amigável?
Vamos comparar as duas implementações de uma função que multiplica um valor por outro pré-definido.
Functor:
https://gist.github.com/thiagomg/f79848f06a939b7fa4b7
Lambda:
https://gist.github.com/thiagomg/abc49253fd507d575647
Note que a referência da variável b será passado junto com a função lambda.
Agora, vamos focar somente no lambda.
O que está sendo inferido?
1. Parâmetro v
2. Retorno, se tem o qual é
3. O tipo do lambda baseado em std::function
https://gist.github.com/thiagomg/033f1a7d68f234343f0c
1. Parâmetro v
2. Retorno: resultado do operador * dos tipos de v e b
3. O tipo do lambda baseado em std::function
https://gist.github.com/thiagomg/52a2cf48ed44739fd81d
1. O tipo do lambda, sendo std::function<int(int)>
https://gist.github.com/thiagomg/4259b8b6fc7074025b14
O lambda tem alguns tipos de captura:
E veja se não fica muito boa a legibilidade.
https://gist.github.com/thiagomg/0d15b70d53aa72ecdbc0
Se esses códigos fossem mostrados para um programador C++ de uns 10 anos atrás, ele certamente não acreditaria que é a mesma linguagem!
Fonte:
https://github.com/SimplyCpp/examples/blob/master/lambda.cpp
https://github.com/SimplyCpp/examples/blob/master/lambda2.cpp
Neste post, quero focar em 5 pontos interessantes sobre estes assuntos. São eles:
1. O que é um lambda?
2. Lambda e Functor, qual a relação entre eles?
3. Como funciona a inferência feita em um lambda?
4. Lista de captura de um lambda
5. Legibilidade interessante
O que é um lambda?
Muito resumidamente, o cálculo lambda (lambda calculus) é uma representação computacional de uma função matemática.
Ex λ: (x, y) -> 2 * x + y
No C++, o lambda é uma função com lista de captura, parâmetros e um retorno (que pode ser void).
Lambda e Functor, qual a relação entre eles?
A implementação de um lambda é a mesma implementação de um functor! Ou seja, o compilador mapeia/transforma um lambda em um functor equivalente.
O lambda tem: lista de captura, função recebendo parâmetros e um retorno
O functor tem: constructor, operador () recebendo parâmetros e um retorno
O lambda é uma maneira interessante para definir um functor anônimo.
Os dois vão virar código inline, mas qual tem a sintaxe mais amigável?
Vamos comparar as duas implementações de uma função que multiplica um valor por outro pré-definido.
Functor:
https://gist.github.com/thiagomg/f79848f06a939b7fa4b7
Lambda:
https://gist.github.com/thiagomg/abc49253fd507d575647
Note que a referência da variável b será passado junto com a função lambda.
Como funciona a inferência feita em um lambda?
Agora, vamos focar somente no lambda.
O que está sendo inferido?
1. Parâmetro v
2. Retorno, se tem o qual é
3. O tipo do lambda baseado em std::function
https://gist.github.com/thiagomg/033f1a7d68f234343f0c
1. Parâmetro v
2. Retorno: resultado do operador * dos tipos de v e b
3. O tipo do lambda baseado em std::function
https://gist.github.com/thiagomg/52a2cf48ed44739fd81d
1. O tipo do lambda, sendo std::function<int(int)>
https://gist.github.com/thiagomg/4259b8b6fc7074025b14
Lista de captura de um lambda
O lambda tem alguns tipos de captura:
[a] -> captura a variável a por valor
[=] -> captura todas as variáveis por valor
[&a] -> captura a variável a por referência
[&] -> captura todas as variáveis por referência
[a, &b] -> captura a por valor e b por referência
[] -> não captura nada
Legibilidade interessante
E veja se não fica muito boa a legibilidade.
https://gist.github.com/thiagomg/0d15b70d53aa72ecdbc0
Se esses códigos fossem mostrados para um programador C++ de uns 10 anos atrás, ele certamente não acreditaria que é a mesma linguagem!
Fonte:
https://github.com/SimplyCpp/examples/blob/master/lambda.cpp
https://github.com/SimplyCpp/examples/blob/master/lambda2.cpp
Comentários
Postar um comentário