Tínhamos uma função que usava um lambda não captador interno para si mesmo, por exemplo:
void foo() {
auto bar = [](int a, int b){ return a + b; }
// code using bar(x,y) a bunch of times
}
Agora, a funcionalidade implementada pelo lambda tornou-se necessária em outro lugar, por isso vou elevar o lambda para foo()
o escopo global / namespace. Posso deixá-lo como um lambda, tornando-o uma opção de copiar e colar ou alterá-lo para uma função adequada:
auto bar = [](int a, int b){ return a + b; } // option 1
int bar(int a, int b){ return a + b; } // option 2
void foo() {
// code using bar(x,y) a bunch of times
}
Mudá-lo para uma função adequada é trivial, mas me fez pensar se há algum motivo para não deixá-lo como um lambda? Existe alguma razão para não usar lambdas em todos os lugares, em vez de funções globais "regulares"?
Respostas:
Há uma razão muito importante para não usar lambdas globais: porque não é normal.
A sintaxe da função regular do C ++ existe desde os dias de C. Os programadores sabem há décadas o que essa sintaxe significa e como eles funcionam (embora seja certo que toda a deterioração de função para ponteiro às vezes morde até programadores experientes). Se um programador de C ++ de qualquer nível de habilidade além de "novato absoluto" vir uma definição de função, ele saberá o que está recebendo.
Um lambda global é um animal completamente diferente. Tem um comportamento diferente de uma função regular. Lambdas são objetos, enquanto funções não. Eles têm um tipo, mas esse tipo é distinto do tipo de sua função. E assim por diante.
Então, agora, você elevou a fasquia na comunicação com outros programadores. Um programador de C ++ precisa entender lambdas se quiser entender o que esta função está fazendo. E sim, isso é 2019, então um programador de C ++ decente deve ter uma idéia de como é um lambda. Mas ainda é uma barra mais alta.
E mesmo que eles entendam, a pergunta na mente do programador será ... por que o escritor desse código o escreveu dessa maneira? E se você não tiver uma boa resposta para essa pergunta (por exemplo, porque deseja proibir explicitamente a sobrecarga, como nos pontos de personalização do Ranges), use o mecanismo comum.
Prefira as soluções esperadas às novas, quando apropriado. Use o método menos complicado de transmitir sua opinião.
fonte
Posso pensar em alguns motivos pelos quais você desejaria evitar lambdas globais como substitutos de entrada para funções regulares:
"Por que eu não deveria usar lambdas para substituir functores com estado (classes)?"
fonte
std::integral_constant
para isso ...Depois de perguntar, pensei em um motivo para não fazer isso: como são variáveis, elas são propensas ao Fiasco da ordem de inicialização estática ( https://isocpp.org/wiki/faq/ctors#static-init-order ), que poderia causar erros na linha.
fonte
constexpr
lambdas ... o ponto real é: basta usar uma função.Um problema de um certo nível de complexidade requer uma solução de pelo menos a mesma complexidade. Mas se houver uma solução menos complexa para o mesmo problema, não há realmente justificativa para usar a mais complexa. Por que introduzir complexidade que você não precisa?
Entre um lambda e uma função, uma função é simplesmente o tipo menos complexo de entidade dos dois. Você não precisa justificar não usar um lambda. Você tem que justificar usando um. Uma expressão lambda apresenta um tipo de fechamento, que é um tipo de classe sem nome com todas as funções-membro especiais usuais, um operador de chamada de função e, nesse caso, um operador de conversão implícito no ponteiro de função e cria um objeto desse tipo. A inicialização de cópia de uma variável global a partir de uma expressão lambda simplesmente faz muito mais do que apenas definir uma função. Ele define um tipo de classe com seis funções declaradas implicitamente, define mais duas funções de operador e cria um objeto. O compilador precisa fazer muito mais. Se você não precisar de nenhum dos recursos de um lambda, não use um lambda…
fonte
Lambdas são funções anônimas .
Se você estiver usando um lambda nomeado, significa que você está basicamente usando uma função anônima nomeada. Para evitar esse oxímoro, você também pode usar uma função.
fonte
Costumávamos usar funções em vez de functor global, por isso quebra a coerência e o Princípio de menor espanto .
As principais diferenças são:
fonte