logo
Contato | Sobre...        
rebarba rebarba

Rodrigo Strauss :: Blog

follow us in feedly

C++11: Range based for loop

Todos os programadores C++ sabem que para percorrer qualquer tipo de container devemos usar iterators e nunca um índice. Certo? Na dúvida, eu já escrevi uma extensa série sobre STL, e escrevi um post só sobre iterators. Lembre-se que se você usa C++ sem STL você está usando C com classes.

Apesar do acesso via iterator ter inúmeras vantagens, ele requer uma dose grande código repetitivo. E isso é incompatível com o fato de que nós, programadores, somos preguiçosos por natureza. Afinal, muita gente começou a programar para automatizar tarefas repetitivas. Como resolver isso?

Dois iterators definem um range (intervalo em pt-br). Eles delimitam o início desse intervalo, com o primeiro item inclusive e o segundo item exclusive (ou seja, o último item de um range **nunca** é válido e aponta para um item após o último item válido). Todos os algoritmos da STL ou compatíveis com a STL trabalham em cima de um par de iterators que define os itens que serão tratados pelo algoritmo (eu também já escrevi sobre algoritmos)

Para percorrer todos os itens de um container (seja ele um vector ou um unordered_map) usando um for nomal, você precisa percorrê-lo do begin() até o end(). Apesar de os containers da STL não implementarem um interface que obrigue isso - já que a STL não usa polimorfismo e sim programação genérica - existe um concept que define que container.begin() e container.end() precisam retornar iterators para o início e o fim do container. A página da saudosa Silicon Graphics sobre STL tem essas definições bem explicadas e documentadas.

Sabendo disso, esse é o código para percorrer todos os itens de um container:

Repetitivo e verbose, certo? O conceito de iterators foi criado para que você possa aplicar um algoritmo à qualquer intervalo de um container, mas na maioria das vezes você faz isso sobre todos os itens. O range based for é um loop que "extrai" automaticamente o range completo de qualquer coisa que você passar para ele.

Veja como fica o código acima usando range based for:

A partir do C++11 o jeito preferido de pegar os iterators é usando as funções livres begin() e end(). Por que? Porque isso torna o código mais genérico. O vector possui begin() e end(), mas o array C não possui e o container de um framework de terceiros também não. Usando as funções livres permite que você crie especializações delas para containers que não sigam os concepts das STL. Veja isso:

Sim, você entendeu direito. O range based for é só um syntax sugar.

Em 01/10/2015 09:25, por Rodrigo Strauss


  
 
 
Comentários
Algo a dizer?
Nome:


Site:


E-mail:


Escreva o número vinte e seis:


 Não mostre meu e-mail no site, não serve pra nada mesmo...

Comentário





Os comentários devem ser sobre assuntos relativos ao post, eu provavelmente apagarei comentários totalmente offtopic. Se quiser me enviar uma mensagem, use o formulário de contato. E não esqueça: isso é um site pessoal e eu me reservo o direito de apagar qualquer comentário ofensivo ou inapropriado.
rebarba rebarba
  ::::