Enviado em 11/05/2016 - 06:22h
https://goparallel.sourceforge.net/can-lambda-functions-speed-c-development/Enviado em 11/05/2016 - 20:13h
Permita-me fazer uma explicação progressiva.#include <stdlib.h> #include <string.h> /* Tipo de dados com um registro qualquer. */ struct registro { char nome[50]; time_t nascimento; }; /* Estrutura usada para representar arrays dinâmicos de registros. */ struct catalogo { struct registro *base; size_t n_regs; }; /* Funções call-back de comparação. Argumentos têm de ser “void *” porque é isso que qsort() exige. Dentro de cada função, convertemos de volta para “struct registro *”. */ int compara_registro_nome(void *pr1, void *pr2){ struct registro *preg1=pr1, *preg2=pr2; return strcoll(preg1->nome, preg2->nome); } int compara_registro_nascimento(void *pr1, void *pr2){ struct registro *preg1=pr1, *preg2=pr2; return preg1->nascimento - preg2->nascimento; } /* Funções que ordenam catálogos. Note que, dentro delas, eu não chamo as funções de comparação, mas apenas as passo como ponteiros de função para que qsort() as invoque nos momentos adequados. */ void ordena_catalogo_nome(struct catalogo *pcat){ qsort(pcat->base, pcat->n_regs, sizeof *pcat->base, compara_registro_nome); } void ordena_catalogo_nascimento(struct catalogo *pcat){ qsort(pcat->base, pcat->n_regs, sizeof *pcat->base, compara_registro_nascimento); }
#include <algorithm> #include <chrono> #include <string> #include <vector> #include <cstring> struct registro { std::string nome; std::chrono::steady_clock::time_point nascimento; }; typedef std::vector<registro> catalogo; /* Funções de comparação retornam true se arg1 vem antes de arg2 */ bool compara_registro_nome(const registro &r1, const registro &r2){ return std::strcoll(r1.nome.c_str(), r2.nome.c_str())<0; } bool compara_registro_nascimento(const registro &r1, const registro &r2){ return r1.nascimento<r2.nascimento; } void ordena_catalogo_nome(catalogo &cat){ std::sort(cat.begin(), cat.end(), compara_registro_nome); } void ordena_catalogo_nascimento(catalogo &cat){ std::sort(cat.begin(), cat.end(), compara_registro_nascimento); }
#include <locale> class comparador_localizado_nome { private: std::locale locale; public: comparador_localizado_nome(): locale() { } comparador_localizado_nome(const std::string &loc_name): locale(loc_name) { } bool operator()(const registro &s1, const registro &s2) const { // Note que nós também usamos “operator()” da classe std::locale return locale(s1.nome, s2.nome)<0; } };
void ordena_catalogo_nome(catalogo &cat, const comparador_localizado_nome &comp_obj){ std::sort(cat.begin(), cat.end(), comp_obj); }
#include <functional> void ordena_catalogo_nome(catalogo &cat, std::function<bool(const registro &, const registro &)> comp=comparador_localizado_nome()){ std::sort(cat.begin(), cat.end(), comp); }(Note que esta última versão torna todas as anteriores desnecessárias.)
int main(void){ catalogo cat; /* Preenche o catálogo com uma grande quantidade de dados. */ // Cria três cópias do catálogo original. catalogo cat_de(cat), cat_fr(cat), cat_es(cat); // Cria objetos do tipo comparador.... comparador_localizado_nome ordena_alemao("de"), ordena_frances("fr"); // ... e ordena usando tais objetos. ordena_catalogo_nome(cat_de, ordena_alemao); ordena_catalogo_nome(cat_fr, ordena_frances); // Ordena usando um objeto temporário. ordena_catalogo_nome(cat_es, comparador_localizado_nome("es")); /* ... */ }
// Ordena por nome (comparação direta de strings) std::sort( cat.begin(), cat.end(), [](const registro &r1, const registro &r2) -> bool { return r1.nome<r2.nome; } ); // Ordena por hora de nascimento. std::sort( cat.begin(), cat.end(), [](const registro &r1, const registro &r2) -> bool { return r1.nascimento<r2.nascimento; } );
auto comp=[](const registro &r1, const registro &r2) -> bool { return r1.nome<r2.nome; }; std::sort(cat.begin(), cat.end(), comp);
#include <iostream> int main(){ int a=0, b=1; double c=2.0, d=1.0; // O lambda recebe cópias dos valores de a e c, e referências para b e d. // Quando ele for invocado (não durante a definição!), os valores de b e d // podem ser modificados, e o bloco de main() verá tais modificações. Se // os valores de a e c não podem ser modificados pelo lambda. auto lambda= [a, &b, c, &d]() -> void { std::cout << "lambda:\t" << a << '\t' << ++b << '\t' << c << '\t' << (d*=1.5) << '\n'; } ; // Outro lambda com cópias dos valores de a e c, e referências para b e d. // Quando ele for invocado (não durante a definição!), os valores de b e d // podem ser modificados, e o bloco de main() verá tais modificações. Como // este lambda tem o atributo “mutable” as cópias de a e c poderão ser alte- // radas, porém tais alterações não se refletem no corpo de main(), mas per- // sistem para o lambda enquanto ele existir. auto lambda2= [a, &b, c, &d]() mutable -> void { std::cout << "lambda:\t" << --a << '\t' << ++b << '\t' << (c/=2) << '\t' << (d*=1.5) << '\n'; } ; std::cout << "main:\t" << a << '\t' << b << '\t' << c << '\t' << d << '\n'; lambda(); std::cout << "main:\t" << a << '\t' << b << '\t' << c << '\t' << d << '\n'; lambda(); std::cout << "main:\t" << a << '\t' << b << '\t' << c << '\t' << d << '\n'; lambda(); std::cout << "main:\t" << a << '\t' << b << '\t' << c << '\t' << d << '\n'; std::cout << '\n'; std::cout << "main:\t" << a << '\t' << b << '\t' << c << '\t' << d << '\n'; lambda2(); std::cout << "main:\t" << a << '\t' << b << '\t' << c << '\t' << d << '\n'; lambda2(); std::cout << "main:\t" << a << '\t' << b << '\t' << c << '\t' << d << '\n'; lambda2(); std::cout << "main:\t" << a << '\t' << b << '\t' << c << '\t' << d << '\n'; }
Resolver problemas de Internet
Como compartilhar a tela do Ubuntu com uma Smart TV (LG, Samsung, etc.)
Descritores de Arquivos e Swappiness
Instalando o WPS em PT-BR e skins no Arch
Atualizando "na marra" o YT-DLP quando começa a dar erro de downloads
Magic SysRq key - O botão de pânico no kernel do seu Linux
Erro na atualização dos apps na barra de tarefas (17)
Chamadas de variável de uma página para outra no PHP8 (4)
Albfneto. Voltando devagar. (7)
HD externo não mostra arquivos (6)
Equipamentos não ligam com a fonte original - NetMetal5 - OmnTik5 (2)