std::vector<int> vec;
vec.push_back(10); // вектор из 1 элементаfor (std::vector<int>::iterator it = vec.begin(); it != vec.end(); it = it + 2)
{
// что-то делаем с it (например в него пишем!)
}
В данном примере условие it != vec.end() никогда не выполняется и мы бесконечно пишем за пределами списка, нарушая кем-то занятую память.
Вопрос:
Можно ли как-то отследить выход за пределы списка?
Здравствуйте, Чили, Вы писали:
Ч>Банальная конструкция: Ч>
Ч>std::vector<int> vec;
Ч>vec.push_back(10); // вектор из 1 элемента
Ч>for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); it = it + 2)
Ч>{
Ч> // что-то делаем с it (например в него пишем!)
Ч>}
Ч>
Ч>В данном примере условие it != vec.end() никогда не выполняется и мы бесконечно пишем за пределами списка, нарушая кем-то занятую память. Ч>Вопрос: Ч>Можно ли как-то отследить выход за пределы списка?
for (std::vector<int>::iterator it = vec.begin(); it != vec.end(),it+1 != vec.end(); it = it + 2)
Здравствуйте, Чили, Вы писали:
Ч>Банальная конструкция: Ч>
Ч>std::vector<int> vec;
Ч>vec.push_back(10); // вектор из 1 элемента
Ч>for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); it = it + 2)
Ч>{
Ч> // что-то делаем с it (например в него пишем!)
Ч>}
Ч>
Ч>В данном примере условие it != vec.end() никогда не выполняется и мы бесконечно пишем за пределами списка, нарушая кем-то занятую память. Ч>Вопрос: Ч>Можно ли как-то отследить выход за пределы списка?
Ну, например так (не компилировал):
template<typename IteratorT>
void safe_advance(IteratorT& i, int increment, IteratorT end)
{
inrement = std::min(increment, std::distance(i, end));
std::advance(i, increment);
}
std::vector<int> vec;
vec.push_back(10); // вектор из 1 элементаfor (std::vector<int>::iterator it = vec.begin(); it != vec.end(); safe_advance(it, 2, vec.end()))
{
// что-то делаем с it (например в него пишем!)
}
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, Alex Dav, Вы писали:
AD>Здравствуйте, Чили, Вы писали:
AD>for (std::vector<int>::iterator it = vec.begin(); it != vec.end(),it+1 != vec.end(); it = it + 2)
Для std::list такое не пройдет
Ч>Можно ли как-то отследить выход за пределы списка?
Для конкретно вектора
for (std::size_t it = 0; it < vec.size(); it = it + 2)
{
// что-то делаем с vec[it] (например в него пишем!)
}
Для листа
for (std::size_t it = 0; it < vec.size(); it = it + 2)
{
std::list<int>::iterator iter;
std::advance( iter = vec.begin(), it );
// что-то делаем с iter (например в него пишем!)
}
Здравствуйте, Чили, Вы писали:
Ч>Банальная конструкция: Ч>
Ч>std::vector<int> vec;
Ч>vec.push_back(10); // вектор из 1 элемента
Ч>for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); it = it + 2)
Ч>{
Ч> // что-то делаем с it (например в него пишем!)
Ч>}
Ч>
Ч>В данном примере условие it != vec.end() никогда не выполняется и мы бесконечно пишем за пределами списка, нарушая кем-то занятую память. Ч>Вопрос: Ч>Можно ли как-то отследить выход за пределы списка?
Я с векторами обычно все-таки пишу так..
std::vector<int> vec;
vec.push_back(10); // вектор из 1 элементаfor (size_t i = 0; i < vec.size(); i += 2)
{
}
Здравствуйте, Caracrist, Вы писали:
C>std::distance --- std::list ?
Для списка тоскливо, конечно, по алгоритмической сложности — O(N). С другой стороны, нужно учитывать специфику задачи. Если больших величин инкремента в рамках конкретной задачи не возникает, то, возможно такая цена за надежность окажется вполне приемлемой.
--
Не можешь достичь желаемого — пожелай достигнутого.
template<typename IteratorT>
void safe_advance(IteratorT& i, int increment, IteratorT end)
{
increment = min(increment, end — i);
std::advance(i, increment);
}
template<typename IteratorT>
void safe_advance_list(IteratorT& i, int increment, IteratorT end)
{
while (increment-->0)
{
if (i != end) i++;
else break;
}
}
std::vector<int> vec;
vec.push_back(10);
for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); safe_advance(it, 2, vec.end()))
{
}
std::list<int> lis;
lis.push_back(10);
for (std::list<int>::iterator it = lis.begin(); it != lis.end(); safe_advance_list(it, 2, lis.end()))
{
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, abrec, Вы писали:
A>Здравствуйте, Alex Dav, Вы писали:
AD>>Здравствуйте, Чили, Вы писали:
AD>>for (std::vector<int>::iterator it = vec.begin(); it != vec.end(),it+1 != vec.end(); it = it + 2)
A>Для std::list такое не пройдет
Здравствуйте, Alex Dav, Вы писали:
AD>Здравствуйте, abrec, Вы писали:
A>>Здравствуйте, Alex Dav, Вы писали:
AD>>>Здравствуйте, Чили, Вы писали:
AD>>>for (std::vector<int>::iterator it = vec.begin(); it != vec.end(),it+1 != vec.end(); it = it + 2)
A>>Для std::list такое не пройдет
AD>почему? it+1 != vec.end()
така арифметика для итераторов произвольного доступа
Здравствуйте, abrec, Вы писали:
A>Здравствуйте, Alex Dav, Вы писали:
AD>>Здравствуйте, Чили, Вы писали:
AD>>for (std::vector<int>::iterator it = vec.begin(); it != vec.end(),it+1 != vec.end(); it = it + 2)
A>Для std::list такое не пройдет
А причем тут std::list? Автор говорил только про std::vector. Для std::list вопрос не имеет смысла, потому что выражение из исходного примера "it = it + 2" не будет работать.
Здравствуйте, Caracrist, Вы писали:
C>std::distance --- std::list ?
Тот же вопрос. Зачем пытаться обобщить на std::list, если никто этого не просит?
Здравствуйте, abrec, Вы писали:
A>>>Для std::list такое не пройдет
AD>>почему? A>it+1 != vec.end() A>така арифметика для итераторов произвольного доступа
Здравствуйте, Alex Dav, Вы писали:
AD>Здравствуйте, Чили, Вы писали:
AD>for (std::vector<int>::iterator it = vec.begin(); it != vec.end(),it+1 != vec.end(); it = it + 2)
Не стоит привязываться к it = it + 2
допустим
for (std::vector<int>::iterator it = vec.begin(); it != vec.end(),it+1 != vec.end(); )
{
if (условие)
it = it + 2;
else
it = it + 3;
else
it = it + 4;
else
...
Здравствуйте, Чили, Вы писали:
Ч>Не стоит привязываться к it = it + 2 Ч>допустим Ч>
Ч>for (std::vector<int>::iterator it = vec.begin(); it != vec.end(),it+1 != vec.end(); )
Ч>{
Ч> if (условие)
Ч> it = it + 2;
Ч> else
Ч> it = it + 3;
Ч> else
Ч> it = it + 4;
Ч> else
Ч> ...
Ч>
Ч>Вполне рабочая конструкция!!!
не спорю что рабочая — в таком случае я бы написал it = it + n;
а для it = it + 2 — мой вариант вполне рабочий
в любом случае — спасибо вам за вопрос — было позновательно почитать ответы
Здравствуйте, Чили, Вы писали:
Ч>Банальная конструкция: Ч>
Ч>std::vector<int> vec;
Ч>vec.push_back(10); // вектор из 1 элемента
Ч>for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); it = it + 2)
Ч>{
Ч> // что-то делаем с it (например в него пишем!)
Ч>}
Ч>
Ч>В данном примере условие it != vec.end() никогда не выполняется и мы бесконечно пишем за пределами списка, нарушая кем-то занятую память. Ч>Вопрос: Ч>Можно ли как-то отследить выход за пределы списка?
Уважаемые коллеги !!!
Вы предлагаете решение частного цикла: Ч>
Ч>for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); it = it + 2)
Ч>{
Ч> // что-то делаем с it (например в него пишем!)
Ч>}
Ч>
а ведь могут быть другие ситуации, напр.: Ч>
Ч>std::vector<int> vec(5);
Ч>std::vector<int>::iterator it = vec.begin()+10; // выход за пределы списка !!!
Ч>
Хочется как-то обезопасить себя от подобных моментов.
Ч>>std::vector<int> vec(5);
Ч>>std::vector<int>::iterator it = vec.begin()+10; // выход за пределы списка !!!
Ч>>
Ч>Хочется как-то обезопасить себя от подобных моментов.
Юзать счётчик религия не позволяет?
std::vector<int> vec;
vec.push_back(10); // вектор из 1 элемента
std::vector<int>::iterator it = vec.begin();
std::vector<int>::iterator itNext = it;
for (unsigned int i = 0; i < vec.size(); it = itNext, i += 2)
{
if(i+2 < vec.size())
{
itNext = itNext+2;
}
// что-то делаем с it (например в него пишем!)
}
std::vector<int> vec(5);
std::vector<int>::iterator it = 10 < vec.size() ? vec.begin()+10 : vec.end();
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
std::vector<int> vec;
vec.push_back(10); // вектор из 1 элементаfor (std::vector<int>::iterator it = vec.begin(); it != vec.end(); )
{
// что-то делаем с it (например в него пишем!)if(it + 1 != vec.end();)
it = it + 2;
else break;
}
Пользоваться указателем на элемент через 1 от последнего нехорошо даже в чисом C массиве.