According to the task, it is necessary to write such a function remove_nth, which rearranges the elements so that the nth element is at the end (by analogy to std :: remove). I chose not the best way, created a structure in which I defined operator () and came across a strange error - this predicate becomes true 2 times if the size of the original collection is more than 2n (n is the number of the element to be deleted). It seems to me that inside the remove_if algorithm it is copied. In this regard, there are 3 questions:

1) Is it really copied inside?

2) Is it possible to write a predicate in such a style that everything works correctly?

3) or is it a bad programming style and a predicate is better defined as a function? (If you write a lambda function that does the same thing, then there will be no error)

#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; } 

    1 answer 1

    Found a solution. The size_t n field can be replaced by size_t & n. And then everything works as expected.

    The explanation for this is.

    The functors passed to the algorithms can be copied within the algorithm an indefinite number of times, so you cannot store the state directly in the functor. On the other hand, you can store a state outside of a functor, using a pointer or a link to some external state structure.