Нужно удалить элемент из std::list
по итератору. Стандарт С++11
и выше не используется. То есть имеется только функция iterator std::list::erase( iterator first, iterator last );
Если я сделаю так, то элемент не удалиться:
void func(std::list<int>& l, std::list<int>::iterator it)
{
l.erase(it, ++it);
}
А если так, то все работает:
void func(std::list<int>& l, std::list<int>::iterator it)
{
std::list<int>::iterator it2 = it;
std::advance(it2, 1);
l.erase(it, it2);
}
Почему? Ведь в erase
в обоих случаях передаются одинаковые итераторы. Есть ли какой способ удалить один элемент из списка без лишних действий?
Вы столкнулись с неопределённым поведением.
Дело в том, что компилятор имеет право вычислять значения аргументов функции в любом порядке. Так что в первом случае он может сначала вычислить и подставить значение второго аргумента (++it
), и только потом — первого (it
).
Во втором же случае значение it2
вычисляется гарантировано до его использования в строке l.erase(it, it2);
благодаря (грубо говоря) наличию точки с запятой.
Всё это является следствием работы механизма точек следования. Подробнее о нём можно почитать, например, в статье «Точки следования (sequence points)» в блоге «Алёна C++».
Порядок вычисления и передачи аргументов в функции не определен. Т.е. компилятор может, например, сначала вычислить ++i
, а потом передавать значение.
Например,
#include <iostream>
#include <iomanip>
using namespace std;
void f(int a, int b)
{
cout << a << " " << b << endl;
}
int main(int argc, const char * argv[])
{
int i = 3;
f(i,++i);
}
здесь, при том, что вы ожидаете 3 4
, реально может быть 4 4
- и не только может, но и VC++, и GCC именно такой результат и дают.
P.S. См. понятие "точка следования".
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
почему при компиляции выдает ошибку где я подключаю
Нужно создать функцию, которая будет вызываться каждую секунду и выполнять определенные действияБез sleep, ибо программа должна выполнять...
Необходимо при выборе папки из QComboBox, показать файлыtif из данной папки в listView
В Qt 48 вызываю функцию getwindowtext, которая во второй параметр выдает заголовок окна