Pergunta

Quando iteração sobre elementos de um vector, é preferível usar iterators em vez de um índice (ver por que usar iteradores em vez de índices de matriz? ).

std::vector<T> vec;
std::vector<T>::iterator it;
for ( it = vec.begin(); it != vec.end(); ++it )
{
   // do work
}

No entanto, pode ser necessário usar o índice no corpo do ciclo. Qual dos seguintes seria preferível nesse caso, considerando o desempenho e flexibilidade / extensibilidade?

  1. Reverter ao indexada loop
    std::vector vec;
    size_t i;
    for ( i = 0; i < vec.size(); ++i )
    {
       // use i
    }
    
  2. Calcular offset
    std::vector vec;
    std::vector::iterator it;
    for ( it = vec.begin(); it != vec.end(); ++it )
    {
       size_t i = it - vec.begin(); 
       // use i
    }
    
  3. Use std :: distância
    std::vector vec;
    std::vector::iterator it;
    for ( it = vec.begin(); it != vec.end(); ++it )
    {
       size_t i = std::distance( vec.begin(), it );
       // use i
    }
    
Foi útil?

Solução

Se você estiver planejando usar exclusivamente um vetor, você pode querer voltar ao lacete indexada, uma vez que transmite a sua intenção mais claramente do que iterador-loop. No entanto, se a evolução do seu programa no futuro pode levar a uma mudança de recipiente, você deve ficar com os iteradores e uso std :: distância, o que é garantido que funcione com todos iterators padrão.

Outras dicas

Usando std :: distância é um pouco mais genérica, uma vez que funciona para todos os iteradores, não apenas iteradores de acesso aleatório. E deve ser tão rápido como ele -. Vec.begin () em caso de iteradores de acesso aleatório

-. Vec.begin () é basicamente a aritmética de ponteiro

std::distance(vec.begin(), it) lhe dará o índice it está apontando para, assumindo que pontos em vec.

Carl

Reverter ao lacete indexada.

Basicamente em 90% dos casos, iteradores são superiores, este é um daqueles 10%. Usando um iterador que você está fazendo o código mais complexo e, portanto, mais difícil de entender, quando toda a razão para usar o iterador em primeiro lugar foi para simplificar o seu código.

Você está perdendo uma solução: manter um índice no caso de você precisar dele, mas não usá-lo como uma condição de loop. Obras em listas também, e os custos (por loop) são O (n) e um registo extra.

Eu sempre tendem para manter com iterators por razões de desenvolvimento futuro.

No exemplo acima, se você talvez decidiu trocar a std :: vector para std :: set (talvez você precisava de uma colecção única de elementos), usando iteradores e distância () iria continuar a trabalhar.

I certeza de que quaisquer problemas de desempenho seria otimizado ao ponto de ser insignificante.

Para vetores, eu sempre usar o método inteiro. Cada um índice para o vector é a mesma velocidade como uma pesquisa de matriz. Se eu vou estar usando o valor de um monte, eu criar uma referência a ele, por conveniência.

iterators vetor pode ser ligeiramente mais rápido do que um índice em teoria, uma vez que eles estão usando a aritmética de ponteiro para percorrer a lista. No entanto, geralmente eu acho que a leitura vale a pena a diferença de tempo de execução mínimo.

Eu uso iterators para outros tipos de contêineres, e às vezes quando você não precisa a variável de loop. Mas se você precisa a variável loop, você não está fazendo nada além de fazer o seu circuito mais difícil tipo. (Eu não posso esperar para auto c ++ 0x de ..)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top