Я наткнулся на эту проблему, работая над небольшим проектом.C++ наиболее неприятный векторный свод кода
#include <iostream>
#include <string>
#include <vector>
int main()
{
std::vector<int*> v;
for (int x = 1; x < 6; ++x)
{
int * a = new int(x);
v.push_back(a);
}
unsigned int y = 4;
for (auto a : v)
{
std::cout << "BEFORE SWAP: v[0] = " << *v[0] << ", v[1] = " << *v[1] << ", v[2] = " << *v[2] << ", v[3] = " << *v[3] << ", v[4] = " << *v[4] << std::endl;
std::swap(a, v[y]);
std::cout << "AFTER SWAP: v[0] = " << *v[0] << ", v[1] = " << *v[1] << ", v[2] = " << *v[2] << ", v[3] = " << *v[3] << ", v[4] = " << *v[4] << std::endl;
std::cout << "==========" << std::endl;
--y;
}
// for (std::vector<int*>::iterator it = v.begin(); it != v.end(); ++it)
// {
// std::cout << "BEFORE SWAP: v[0] = " << *v[0] << ", v[1] = " << *v[1] << ", v[2] = " << *v[2] << ", v[3] = " << *v[3] << ", v[4] = " << *v[4] << std::endl;
// std::swap(*it, v[y]);
// std::cout << "AFTER SWAP: v[0] = " << *v[0] << ", v[1] = " << *v[1] << ", v[2] = " << *v[2] << ", v[3] = " << *v[3] << ", v[4] = " << *v[4] << std::endl;
// std::cout << "==========" << std::endl;
// --y;
// }
// inb4 "You forgot to deallocate!" This is an example.
}
В конце кода есть две петли, которые выполняют ту же задачу, но по-другому.
для цикла с auto
ключевого слова производит этот результат с пропущенными числами:
BEFORE SWAP: v[0] = 1, v[1] = 2, v[2] = 3, v[3] = 4, v[4] = 5
AFTER SWAP: v[0] = 1, v[1] = 2, v[2] = 3, v[3] = 4, v[4] = 1
==========
BEFORE SWAP: v[0] = 1, v[1] = 2, v[2] = 3, v[3] = 4, v[4] = 1
AFTER SWAP: v[0] = 1, v[1] = 2, v[2] = 3, v[3] = 2, v[4] = 1
==========
BEFORE SWAP: v[0] = 1, v[1] = 2, v[2] = 3, v[3] = 2, v[4] = 1
AFTER SWAP: v[0] = 1, v[1] = 2, v[2] = 3, v[3] = 2, v[4] = 1
==========
BEFORE SWAP: v[0] = 1, v[1] = 2, v[2] = 3, v[3] = 2, v[4] = 1
AFTER SWAP: v[0] = 1, v[1] = 2, v[2] = 3, v[3] = 2, v[4] = 1
==========
BEFORE SWAP: v[0] = 1, v[1] = 2, v[2] = 3, v[3] = 2, v[4] = 1
AFTER SWAP: v[0] = 1, v[1] = 2, v[2] = 3, v[3] = 2, v[4] = 1
==========
для цикла с итератор работает, как ожидалось:
BEFORE SWAP: v[0] = 1, v[1] = 2, v[2] = 3, v[3] = 4, v[4] = 5
AFTER SWAP: v[0] = 5, v[1] = 2, v[2] = 3, v[3] = 4, v[4] = 1
==========
BEFORE SWAP: v[0] = 5, v[1] = 2, v[2] = 3, v[3] = 4, v[4] = 1
AFTER SWAP: v[0] = 5, v[1] = 4, v[2] = 3, v[3] = 2, v[4] = 1
==========
BEFORE SWAP: v[0] = 5, v[1] = 4, v[2] = 3, v[3] = 2, v[4] = 1
AFTER SWAP: v[0] = 5, v[1] = 4, v[2] = 3, v[3] = 2, v[4] = 1
==========
BEFORE SWAP: v[0] = 5, v[1] = 4, v[2] = 3, v[3] = 2, v[4] = 1
AFTER SWAP: v[0] = 5, v[1] = 2, v[2] = 3, v[3] = 4, v[4] = 1
==========
BEFORE SWAP: v[0] = 5, v[1] = 2, v[2] = 3, v[3] = 4, v[4] = 1
AFTER SWAP: v[0] = 1, v[1] = 2, v[2] = 3, v[3] = 4, v[4] = 5
==========
Что происходит с петлей auto
? Почему я теряю ценности?
Вот ссылка CPP.SH, чтобы увидеть для себя: http://cpp.sh/2ve3
Подобно Абхишеку, в итераторе альтернатива 'it' является логически ссылкой на векторный элемент, но' auto a' является просто копией. Попробуйте 'auto & a', и он должен работать так, как ожидалось. – enobayram
@enobayram Это работает. Мне всегда казалось, что 'auto a' в этом случае уже есть ссылки. –
обратите внимание также, что самая неприятная проблема синтаксического анализа в 'C++' относится к чему-то совершенно другому. –