Pular para o conteúdo principal

Legibilidade com C++14 - get_numeric

Eu escrevi um código em C++ há um tempo atrás e quando olhei hoje vi como a legibilidade mudou desde o C++11.

Neste código eu vi algumas coisas interessantes. Ele serve bem de exemplo para alguns tipos de codificação

  1. Codificação concreta

  2. Codificação genérica

  3. Codificação concreta com C++ moderno

  4. Codificação genérica com C++ moderno


Vamos ver agora cada um deles.


O algoritmo


O algoritmo que eu implementei é bem simples. Ele itera em uma std::string de entrada e copia somente os caracteres não numéricos para a string de saída.
Ex: "12asew3d45ddf678ee9 0" => "1234567890"

Codificação concreta


Essa é a versão mais simples de todas, de implementar e de entender.

https://gist.github.com/thiagomg/29f45db0e8fc0ea6166e

Nós estamos usando o for_each com um Functor numerical_appender para que ele adicione na string de saída somente os caracteres numéricos.

É uma implementação trivial. Para cada caractere da entrada, o operator() será chamado.

Codificação genérica


Aqui nós temos uma diferença básica. Ao invés de receber uma string, o algoritmo trabalha com iteradores somente e dessa forma suporta qualquer tipo de vetor, podendo ser uma string, vector, list, etc...

https://gist.github.com/thiagomg/07b7ace3c40be2865c67

Codificação concreta com C++ moderno


C++ 11 e o lambda vieram facilitar a nossa vida e melhorar a legibilidade realmente.
Vamos fazer a implementação concreta da nossa função:

https://gist.github.com/thiagomg/5b2d06a923d1a8af6fed

Bem mais simples!

Temos agora uma função encadeada dentro de get_numeric e fazendo o filtro.

Codificação genérica com C++ moderno


Agora temos uma surpresa interessante. Vejamos a diferença dela para a versão concreta.

https://gist.github.com/thiagomg/d9877aaac2f86b7b1759

Note que ela é quase igual à versão concreta. Temos o template de diferença e o auto no lambda. Fácil, não acha?

C++ 14 - STL


No C++ 14 (desde o C++ 11, na verdade) temos um método novo na STL chamado copy_if. Esse método faz basicamente o que o std::copy faz, porém tendo um predicado para definir se o caractere será copiado.

https://gist.github.com/thiagomg/ade42c7a04e70c448760

Simples, não?

Uma outra forma de implementar esse mesmo método seria usar o iterador com predicado. Fica para quem tiver curiosidade:
http://simplycpp.com/2015/10/13/iterator-com-predicado-o-que-e-isso/

Referências


Fonte:



  • https://github.com/SimplyCpp/examples/blob/master/numeric.cpp


Referências:



  • http://www.cplusplus.com/reference/algorithm/copy_if/

  • http://www.cplusplus.com/reference/algorithm/for_each/

Comentários

Postagens mais visitadas deste blog

Mestre Iota

Iota é a nona letra do alfabeto grego, ela é equivalente à letra i do nosso alfabeto. Por convenção ou hábito, utilizamos a letra i na programação para indicar algum tipo de incrementador, como por exemplo, em um for-loop . https://gist.github.com/fabiogaluppo/a23894ae743f7dd29274 Curiosamente, iota , como identificador, também é utilizado na programação para indicar uma sequência finita e consecutiva de números inteiros, como por exemplo, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]. Inclusive, originalmente na STL existia a função iota , inspirada pela linguagem de programação APL , você pode conferir neste link: http://www.sgi.com/tech/stl/iota.html

Valores Aleatórios Simplificados

A partir do C++ 11, foi introduzido o header <random>  com diversos facilitadores para suporte de geração de números aleatórios. A produção destes números é feita através da combinação de duas categorias de objetos: os geradores e os distribuidores. Os geradores, são responsáveis pela geração dos números, e os distribuidores são responsáveis pela transformação dos números gerados em algum tipo de distribuição de probabilidade.  Como por exemplo, uma distribuição normal (aquela da Gaussiana) ou uma distribuição de Pareto (aquela do 80-20). As opções não faltam, como você pode ver nas referências, por exemplo:   http://www.cplusplus.com/reference/random/ ou  http://en.cppreference.com/w/cpp/header/random .

Policy-based design: log writer

Policy-based design Vamos neste artigo dar mais uma pincelada no Policy-based design . Vamos fazer como exemplo uma classe de log. Como este é só um exemplo, não vamos considerar múltiplos parâmetros no log, mas somente uma string, assim não fugiremos do assunto. Uma das coisas mais importantes neste tipo de design é o desacoplamento. Ele é uma excelente alternativa ao uso de interfaces por duas razões: Não gera chamadas virtuais (ou um nível de indireção em tempo de execução) Duck typing ( https://pt.wikipedia.org/wiki/Duck_typing ) Eu gosto bastante desse tipo de design, já usado aqui: http://simplycpp.com/2016/02/05/leitura-de-configuracao-em-c/