Проблема: Синтаксическая конструкция цикла for для итераторов стандартна.
// code
for(auto it = p; it != q; ++it){...}
// another code
И это, кажется, работало. Но я столкнулся с тем, что условие it != q не проходит в коде ниже. Просто не срабатывает и происходит обращение за пределы контейнера. Знаю, что end указывает ЗА последний элемент, но как это мешает работе?
template<class FwdIt>
FwdIt remove_nth(FwdIt p, FwdIt q, size_t n)
{
// smth
for (auto it = ++p; it != q;++it)
{
auto next = p;
*p = *++next;
p = next;
}
//smth
}
Вызов происходит так:
std::vector<int> v = {0,1,2,3,4,5,6,7,8,9,10};
v.erase(remove_nth(v.begin(), v.end(), 5), v.end());
Впорос: Что я делаю не так? Я пропустил что-то существенное в освоении работы с итераторами? Про range-based знаю, но здесь он не годен.
remove_nth() переносит элемент, который n номера, в конец. erase подчищает его.
Удалить N-й элемент вектора:
v.erase(v.begin()+N);
Удалить K элементов начиная с N-го
v.erase(v.begin()+N, v.begin()+N+K);
remove_nth() переносит элемент, который n номера, в конец.
Как-то так:
template<class FwdIt>
FwdIt moveNToEnd(FwdIt p, FwdIt q, size_t n) {
assert (std::distace (p,q) < n);
std::advance (p, n);
auto val = *p;
FwdIt prev = p++;
for (;p!= q;) {
*prev++ = *p++;
}
*prev = val;
return prev
}
Замечания:
std::list
) можно сделать это более эффективно.Цикл можно было оформить так. Полностью соответствует требуемому. В std::cout отладочный вывод
auto last = p;
if (p != q) {
for (auto it = ++p; it != q; ++it)
{
std::cout << " before: it " << *it << "; last " << *last << std::endl;
std::swap(*last, *it);
std::cout << "after: it " << *it << "; last " << *last << std::endl;
++last;
p = it;
}
}
Ошибки в вашей функции очевидные, вам об этом рассказали в комментарих. Функция пишется просто:
template<class FwdIt>
FwdIt remove_nth(FwdIt p, FwdIt q, const size_t n)
{
FwdIt first = p + n; // нужно сохранять значение начала `p`
for (auto it = first + 1; it != q;++it)
*first++ = *it;
return first;
}
Я думаю вам нужна отдельная функция, не требующая дальнейшее использование методов контейнера для удаления элемента: Приведу пример:
template<class ClassType, class For = typename ClassType::iterator>
ClassType my_remove(ClassType& cont, For p, For q, const size_t n)
{
if(typeid(typename std::iterator_traits<For>::iterator_category)
!= typeid(std::random_access_iterator_tag) || size_t(q - p) <= n)
return cont;
For It = std::remove(p, q, n);
//или используйте вашу собственную функцию
// For It = remove_nth(p, q, n);
return ClassType(p, It);;
}
int main()
{
std::vector<int> v = {0,1,2,3,4,5,6,7,8,9,10},
res = my_remove(v, v.begin(), v.end(), 4);
for (int i : res)
cout << i << ' ';
return 0;
}
Виртуальный выделенный сервер (VDS) становится отличным выбором
Хочу воспользоваться первым вариантом этого метода, чтобы генерировать псевдослучайные числа с нормальным распределением
как можно запретить ввод букв внутри терминала? Жмем клавишу, программа сразу отрабатывает, понимает, что это буква и ничего не происходитЖмем...
Изучаю Spring на IDE IntelJIdeaХочу почитать что делает тот или иной метод, аннотация