Eu sou novo na linguagem C ++. Eu comecei a usar vetores e notei que em todo o código que vejo para iterar por um vetor por índices, o primeiro parâmetro do for
loop é sempre algo baseado no vetor. Em Java, eu poderia fazer algo assim com um ArrayList:
for(int i=0; i < vector.size(); i++){
vector[i].doSomething();
}
Existe uma razão para eu não ver isso em C ++? É uma má prática?
c++
coding-style
for-loop
iterator
Flynn
fonte
fonte
std::vector<int>::size_type i = 0;
, ou talvezstd::vector<int>::iterator it = vector.begin();
?std::vector
? , o Q real que está sendo perguntado aqui é: Existe algum motivo para eu não ver isso em C ++? É uma má prática? aka Por que sempre vejo código em C ++ que usa iteradores durante a iteraçãostd::vector
?Respostas:
Não. Não é uma prática ruim, mas a abordagem a seguir confere ao seu código certa flexibilidade .
Geralmente, antes do C ++ 11, o código para iterar sobre elementos de contêiner usa iteradores, algo como:
Isso ocorre porque torna o código mais flexível.
Todos os contêineres de biblioteca padrão suportam e fornecem iteradores. Se, posteriormente, você precisar mudar para outro contêiner, esse código não precisará ser alterado.
Nota: Escrever código que funcione com todos os contêineres de biblioteca padrão possíveis não é tão fácil quanto parece.
fonte
auto
.A razão pela qual você não vê essa prática é bastante subjetiva e não pode ter uma resposta definitiva, porque eu vi muitos dos códigos que usam sua maneira mencionada e não o
iterator
estilo.A seguir, pode haver razões pelas quais as pessoas não consideram a
vector.size()
maneira de fazer um loop:size()
todas as vezes na condição de loop. No entanto, não é um problema ou pode ser corrigido trivialmentestd::for_each()
sobre ofor
próprio loopstd::vector
para outro (por exemplomap
,list
) também exigirá a alteração do mecanismo de loop, porque nem todo contêiner suporta osize()
estilo de loopO C ++ 11 fornece uma boa facilidade para percorrer os contêineres. Isso é chamado de "intervalo baseado em loop" (ou "aprimorado para loop" em Java).
Com pouco código, você pode percorrer o total (obrigatório!)
std::vector
:fonte
#pragma omp parallel for
.A maneira mais limpa de iterar através de um vetor é através de iteradores:
ou (equivalente ao acima)
Antes do C ++ 0x, é necessário substituir auto pelo tipo de iterador e usar funções-membro em vez de funções globais começarem e terminarem.
Provavelmente é isso que você viu. Comparado à abordagem mencionada, a vantagem é que você não depende muito do tipo de
vector
. Se você mudarvector
para uma classe "tipo de coleção" diferente, seu código provavelmente ainda funcionará. No entanto, você pode fazer algo semelhante em Java. Não há muita diferença conceitualmente; C ++, no entanto, usa modelos para implementar isso (em comparação com genéricos em Java); portanto, a abordagem irá funcionar para todos os tipos para os quaisbegin
eend
funções são definidas, mesmo para os tipos não-classe, tais como matrizes estáticos. Veja aqui: Como o intervalo de trabalho funciona para matrizes simples?fonte
begin
eend
, no entanto, é unilateral.auto
por outro lado, seria bastante complicado.A maneira correta de fazer isso é:
Onde T é o tipo da classe dentro do vetor. Por exemplo, se a classe for CActivity, basta escrever CActivity em vez de T.
Esse tipo de método funcionará em todos os STL (não apenas nos vetores, o que é um pouco melhor).
Se você ainda deseja usar índices, o caminho é:
fonte
std::vector<T>::size_type
sempresize_t
? Esse é o tipo que eu sempre uso para isso.Existem algumas razões fortes para usar iteradores, alguns dos quais são mencionados aqui:
A troca de contêineres posteriormente não invalida seu código.
ou seja, se você passar de um vetor std :: para uma lista std :: ou std :: set, não poderá usar índices numéricos para obter o valor contido. O uso de um iterador ainda é válido.
Captura em tempo de execução de iteração inválida
Se você modificar seu contêiner no meio do seu loop, na próxima vez em que usar seu iterador, ele lançará uma exceção de iterador inválida.
fonte
Fiquei surpreso que ninguém mencionou que a iteração através de uma matriz com um índice inteiro facilita a gravação de código defeituoso ao inscrever uma matriz com o índice errado. Por exemplo, se você tiver aninhado loops usando
i
ej
como índices, poderá subscrever incorretamente uma matriz comj
e nãoi
e assim introduzir uma falha no programa.Por outro lado, as outras formas listadas aqui, a saber, o
for
loop baseado em intervalo e os iteradores, são muito menos propensos a erros. A semântica da linguagem e o mecanismo de verificação de tipo do compilador impedirão que você acesse acidentalmente uma matriz usando o índice errado.fonte
Com o STL, os programadores usam
iterators
para percorrer contêineres, já que o iterador é um conceito abstrato, implementado em todos os contêineres padrão. Por exemplo,std::list
não tem nadaoperator []
.fonte
O uso do operador automático facilita o uso, pois não é necessário se preocupar com o tipo de dados e o tamanho do vetor ou qualquer outra estrutura de dados.
Iterando vetor usando auto e for loop
Resultado:
Você também pode usar esse método para iterar conjuntos e listar. O uso de auto detecta automaticamente o tipo de dados usado no modelo e permite usá-lo. Assim, mesmo se tivéssemos uma
vector
destring
ouchar
a mesma sintaxe vai funcionar muito bemfonte
A maneira correta de iterar o loop e imprimir seus valores é a seguinte:
fonte
Aqui está uma maneira mais simples de iterar e imprimir valores em vetor.
fonte
fonte