Pular para o conteúdo principal

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

A função std::iota como é percebido foi (re)introduzida no C++ 11. Ela é definida no header <numeric>: http://www.cplusplus.com/reference/numeric/iota/. Seu propósito é fornecer uma sequência consecutiva dentro de um intervalo fornecido por um par de iterators [begin, end) a partir de valor inicial. A sequência consecutiva é gerada através da aplicação de uma função sucessora, que no caso geral é um pré-incremento, onde no C++ isto representa ++i.

Abaixo alguns exemplos do uso da função std::iota com uma diversidade de pares de iterator e valores iniciais:

https://gist.github.com/fabiogaluppo/e288286749a6bb58b06b

Não seria interessante se estas sequências fossem alteradas, ou seja, se conseguíssemos alterar o comportamento da função sucessora de forma determinística ou não? E a resposta é sim! É possível alterarmos o comportamento padrão do operator++, uma vez que encapsulamos para um tipo convertível ao tipo do ForwardIterator indicado (os dois argumentos iniciais de std::iota são iterators, assim como a maioria dos algoritmos expostos pela STL), e este tipo tenha implementado o operador de pré-incremento. Algo como o tipo iota_step sugerido abaixo:

https://gist.github.com/fabiogaluppo/39d3a8ca29487d4ca4a3

Você poderá utilizar o iota_step juntamente com std::iota da seguinte forma:

https://gist.github.com/fabiogaluppo/80d467c295edcde1718c

Ou se preferir utilizar uma função para construir o iota_step e se beneficiar da inferência do tipo:

https://gist.github.com/fabiogaluppo/65cfd63ac47764be711e

Comentei acima que poderia fazer isto de forma não determinística, neste caso, que a função sucessora seja imprevisível ou aleatória. Basta seguir as mesmas considerações do iota_step e programar o operator++ com algum tipo de gerador de números pseudoaleatórios, como segue:

https://gist.github.com/fabiogaluppo/64eb9045e9ab5621cb07

Assim você utilizará a característica básica de std::iota através de um comportamento estendido. Isto é divertido ou no mínimo curioso, não acha?

BTW, este post não é uma homenagem ao despertar da força! ;-)

Fontes:
https://github.com/SimplyCpp/examples/blob/master/understanding_iota.hpp
https://github.com/SimplyCpp/examples/blob/master/understanding_iota_program.cpp

Comentários

  1. […] é um algoritmo de operação numérica que, da mesma forma que std::iota explorado anteriormente (http://simplycpp.com/2015/11/06/mestre-iota/), reside no header <numeric> da STL: […]

    ResponderExcluir

Postar um comentário

Postagens mais visitadas deste blog

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/