Почему этот код записывает неопределенное количество, казалось бы, неинициализированных целых чисел?
#include <iostream>
#include <vector>
using namespace std;
int main()
{
for (int i : vector<vector<int>>{{77, 777, 7777}}[0])
cout << i << ' ';
}
Я ожидал, что результат будет 77 777 7777
.
Этот код должен быть неопределенным?
using std::vector
вместоusing namespace std;
того, чтобы предотвратить распространение этой плохой практики.Это потому, что вектор, который вы перебираете, будет уничтожен перед входом в цикл.
Это то, что обычно происходит:
Проблемы начинаются с первой строки, потому что она оценивается следующим образом:
Сначала создайте вектор векторов с заданными аргументами, и этот вектор станет временным, потому что у него нет имен.
Тогда ссылка на диапазон привязывается к подписанному вектору, который будет действителен только в том случае, если допустим вектор, который его содержит.
Как только точка с запятой достигнута, временный вектор уничтожается, и в своем деструкторе он уничтожает и освобождает любые сохраненные векторы, включая индексированный.
В итоге вы получите ссылку на уничтоженный вектор, который будет повторяться.
Чтобы избежать этой проблемы, есть два решения:
Объявите вектор перед циклом, чтобы он продолжался до тех пор, пока не закончится его область действия, которая включает цикл.
C ++ 20 поставляется с оператором init, который предназначен для решения этих проблем и лучше первого подхода, если вы хотите, чтобы вектор был уничтожен сразу после цикла:
источник
Я ожидаю, что это болтается.
Хотя определение дальнего радиуса действия гарантирует, что RHS ободочной кишки остается «живым» на время, вы все еще подписываетесь на временную подписку. Сохраняется только результат нижнего индекса, но этот результат является ссылкой, и фактический вектор не может выжить после полного выражения, в котором он объявлен. Это не описывает весь цикл.
источник