Por que esse código grava um número indefinido de números inteiros aparentemente não inicializados?
#include <iostream>
#include <vector>
using namespace std;
int main()
{
for (int i : vector<vector<int>>{{77, 777, 7777}}[0])
cout << i << ' ';
}
Eu esperava que a saída fosse 77 777 7777
.
Esse código deveria estar indefinido?
using std::vector
vez deusing namespace std;
para impedir que essa má prática se espalhe.Isso ocorre porque o vetor sobre o qual você está repetindo será destruído antes de entrar no loop.
Isto é o que normalmente acontece:
Os problemas começam na primeira linha porque é avaliado da seguinte maneira:
Primeiro, construa o vetor de vetores com os argumentos fornecidos e esse vetor se torna temporário porque não possui nomes.
Em seguida, a referência de intervalo é vinculada ao vetor subscrito, que só será válido enquanto o vetor que o contém for válido.
Quando o ponto-e-vírgula é atingido, o vetor temporário é destruído e, em seu destruidor, ele destrói e desaloca qualquer vetor armazenado que inclua o vetor subscrito.
Você termina com uma referência a um vetor destruído que será repetido.
Para evitar esse problema, existem duas soluções:
Declare o vetor antes do loop para que ele dure até que seu escopo termine, incluindo o loop.
O C ++ 20 vem com uma instrução init que é fornecida para resolver esses problemas e é melhor que a primeira abordagem se você deseja que o vetor seja destruído imediatamente após o loop:
fonte
Espero que isso esteja oscilando.
Embora a definição de um intervalo para garantir que o RHS do cólon permaneça "vivo" durante o período, você ainda está inscrevendo um temporário. Somente o resultado do subscrito é mantido, mas esse resultado é uma referência, e o vetor real não pode sobreviver após a expressão completa em que foi declarado. Isso não descreve o loop inteiro.
fonte