По заданию необходимо написать такую функцию remove_nth, которая переставляет элементы таким образом, чтобы n-ый элемент оказался в конце(по аналогии std::remove). Я выбрал не самый лучший способ, создал структуру, в которой определил operator() и наткнулся на странную ошибку - данный предикат становится верным 2 раза, если размер исходной коллекции более, чем 2n (n - номер удаляемого элемента). Как мне кажется, внутри алгоритма remove_if он копируется. В связи с этим есть 3 вопроса:
1) действительно ли он копируется внутри?
2) возможно ли написать предикат в таком стиле, чтобы все работало правильно?
3) или это плохой стиль программирования и предикат лучше определять как функцию?(если написать лямбда-функцию, делающую тоже самое, то ошибки не будет)
#include <algorithm>
#include <vector>
#include <iostream>
template<class FwdIt>
struct validator
{
using Val = typename std::iterator_traits<FwdIt>::value_type;
size_t n;
validator(int _n) : n(_n) {}
bool operator()(Val & el)
{
return (n-- == 0);
}
};
template<class FwdIt>
FwdIt remove_nth(FwdIt p, FwdIt q, size_t n)
{
return std::remove_if(p, q, validator<FwdIt>(n));
}
int main()
{
std::vector<int> v = { 0,1,2,3,4, 5,6,7,8,9,10, 11 };
auto a = remove_nth(v.begin(), v.end(), 5);
for (auto it = v.begin(); it != a; ++it)
{
std::cout << *it << " ";
}
std::cout << std::endl;
for (auto it = v.begin(); it != v.end(); ++it)
{
std::cout << *it << " ";
}
return 0;
}
Нашел решение. Поле size_t n можно заменить на size_t & n. И тогда все работает, как и предполагалось.
Объяснение у этого такое .
Функторы, переданные алгоритмам, могут быть скопированы внутри алгоритма неопределенным числом раз, поэтому вы не можете хранить состояние непосредственно в функторе. С другой стороны, вы можете хранить состояние вне функтора, используя указатель или ссылку на некоторую внешнюю структуру состояния.
Продвижение своими сайтами как стратегия роста и независимости