ti-enxame.com

Qual é a diferença entre std :: advance e std :: next?

Existe mais do que o avanço leva números negativos?

56
Tavison

std::advance

  • modifica seu argumento
  • não retorna nada
  • funciona em iteradores de entrada ou melhor (ou iteradores bidirecionais se for dada uma distância negativa)

std::next

  • deixa seu argumento não modificado
  • retorna uma cópia do argumento, avançado pela quantidade especificada
  • funciona em iteradores avançados ou melhor (ou iteradores bidirecionais se for dada uma distância negativa))
87
Benjamin Lindley

Talvez a maior diferença prática seja que std::next() está disponível apenas no C++ 11.

std::next() avançará um por padrão, enquanto std::advance() requer uma distância.

E depois há os valores de retorno:

std::next() recebe números negativos como std::advance e, nesse caso, exige que o iterador seja bidirecional. std::prev() seria mais legível quando a intenção é especificamente retroceder.

15
Johnsyweb

std :: advance

A função advance () incrementa a posição de um iterador passado como argumento. Assim, a função permite que o iterador avance (ou retroceda) mais de um elemento:

#include <iterator>
void advance (InputIterator& pos, Dist n)
  • Permite que o iterador de entrada poste os elementos da etapa n para frente (ou para trás).
  • Para iteradores bidirecionais e de acesso aleatório, n pode ser negativo para retroceder.
  • Dist é um tipo de modelo. Normalmente, ele deve ser do tipo integral, pois operações como <, ++, - e comparações com 0 são chamadas.
  • Observe que advance () não verifica se cruza o final () de uma sequência (não pode verificar porque os iteradores em geral não conhecem os contêineres nos quais operam). Portanto, chamar essa função pode resultar em um comportamento indefinido, pois a chamada do operador ++ para o final de uma sequência não está definida.

std :: next (e std::prev novo no C++ 11)

#include <iterator>
ForwardIterator next (ForwardIterator pos)
ForwardIterator next (ForwardIterator pos, Dist n)
  • Rende a posição que o iterador anterior teria se movido para a frente 1 ou n posições.
  • Para iteradores bidirecionais e de acesso aleatório, n pode ser negativo para gerar as anteriores.
  • Dist é do tipo std :: iterator_traits :: difference_type.
  • Chamadas adiantadas (pos, n) para um objeto temporário interno.
  • Observe que next () não verifica se cruza o final () de uma sequência. Portanto, cabe ao chamador garantir que o resultado seja válido.

cite de The C++ Standard Library Second Edition

6
billz

Eles são praticamente iguais, exceto que std::next Retorna uma cópia e std::advance Modifica seu argumento. Observe que o padrão exige que std::next Se comporte como std::advance:

24.4.4 Operações do iterador [iterator.operations]

template <class InputIterator, class Distance>
void advance(InputIterator& i [remark: reference], Distance n);

2. Requer: n deve ser negativo apenas para iteradores de acesso bidirecional e aleatório
3. Efeitos: Incrementa (ou diminui para n negativo) a referência do iterador i por n.
[...]

template <class ForwardIterator>
ForwardIterator next(ForwardIterator x, [remark: copy]
     typename std::iterator_traits<ForwardIterator>::difference_type n = 1);

6. Efeitos: Equivalente a advance(x, n); return x;

Observe que ambos realmente suportam valores negativos se o iterador for um iterador de entrada. Observe também que std::next Exige que o iterador atenda às condições de um ForwardIterator, enquanto std::advance Precisa apenas de um iterador de entrada (se você não usar distâncias negativas).

3
Zeta