Pergunta

Esta é uma questão que vai para a forma como cheques BOOST_FOREACH-lo de rescisão de loop

cout << "Testing BOOST_FOREACH" << endl;
vector<int> numbers; numbers.reserve(8);
numbers.push_back(1); numbers.push_back(2); numbers.push_back(3);
cout << "capacity = " << numbers.capacity() << endl;
BOOST_FOREACH(int elem, numbers)
{
    cout << elem << endl;
    if (elem == 2) numbers.push_back(4); 
}
cout << "capacity = " << numbers.capacity() << endl;

dá a saída

Testing BOOST_FOREACH
capacity = 8
1
2
3
capacity = 8

Mas o que sobre o número 4, que foi inserida a meio do loop? Se eu alterar o tipo de uma lista o número recém-inserido será iterado. A operação vector push_back invalidará qualquer ponteiros IF uma realocação é necessária, no entanto, que não está acontecendo neste exemplo. Então, a pergunta que eu acho que é por isso que faz o end () iterator aparecem apenas para ser avaliada uma vez (antes do loop) ao usar vetor, mas tem uma avaliação mais dinâmica ao usar uma lista?

Foi útil?

Solução

debaixo das cobertas, usos BOOST_FOREACH iterators para atravessar o elemento seqüência. Antes do laço é executado, o iterador final é armazenado em cache em um local, variável. Isso é chamado de elevação, e é uma otimização importante. isto assume, no entanto, que a extremidade iteração da sequência é estável. isto normalmente é, mas se nós modificar o sequência, adicionando ou removendo elementos enquanto estamos iterando -lo, nós pode acabar elevação nos na nossa própria armadilha.

http://www.boost.org/ doc / libs / 1_40_0 / doc / html / foreach / pitfalls.html

Se você não quer que o end () iterator ao uso de redimensionamento mudança no vetor em vez de reserva.

http://www.cplusplus.com/reference/stl/vector/resize /

Note que, em seguida, você não gostaria de push_back mas usar o operador [] em vez. Mas tenha cuidado de sair dos limites.

Outras dicas

A questão foi levantada nos comentários a respeito de porque a depuração de tempo de execução Microsoft levanta uma afirmação durante a iteração sobre o vetor, mas não sobre a lista. A razão é que insert é definido de forma diferente para list e vector (nota que push_back é apenas um insert no final da sequência).

acordo com a norma C ++ (ISO / IEC 14882: 2003 23.2.4.3, vector modificadores ):

[na inserção], se nenhuma realocação acontece, todos os iteradores e referências antes do ponto de inserção permanecem válidas.

(23.2.2.3, lista modificadores ):

[inserir] não afeta a validade de iteradores e referências.

Então, se você usar push_back (e temos a certeza que não vai causar uma redistribuição), está tudo bem com qualquer recipiente para continuar usando o iterador para iterar sobre o resto da sequência.

No caso do vector, no entanto, é comportamento indefinido para utilizar o iterador end que você obteve antes do push_back.

Esta é uma resposta indireta à pergunta; é uma resposta direta à discussão nos comentários da pergunta.

foreach do impulso irá terminar quando é iterador == numbers.end ()

Tenha cuidado, porém, chamando push_back lata / invalida qualquer iteradores atuais que você tem.

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