копирование предиката в remove_if

150
14 ноября 2019, 20:00

По заданию необходимо написать такую функцию 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;
}
Answer 1

Нашел решение. Поле size_t n можно заменить на size_t & n. И тогда все работает, как и предполагалось.

Объяснение у этого такое .

Функторы, переданные алгоритмам, могут быть скопированы внутри алгоритма неопределенным числом раз, поэтому вы не можете хранить состояние непосредственно в функторе. С другой стороны, вы можете хранить состояние вне функтора, используя указатель или ссылку на некоторую внешнюю структуру состояния.

READ ALSO
С++ Обмен данными в локальной сети

С++ Обмен данными в локальной сети

Ситуация: Реализую программу для управления компьютерами локальной сети на С++Вопрос: Как отправить структуру данных от клиента и принять...

139
Разница между inline и static переменной

Разница между inline и static переменной

В 17 стандарте есть новая фича: inline переменныеНо я не совсем понимаю, а в чем разница между inline и static переменной?

187
Слишком мало аргументов для вызова

Слишком мало аргументов для вызова

Только начал писать программу, и уже застрялВ 17 строке (5 снизу)

140
Как с помощью Clang собрать библиотеку из исходного кода на Windows

Как с помощью Clang собрать библиотеку из исходного кода на Windows

Что нужно сделать, чтобы получить статическую/динамическую GLFW (или любую другую, в которой имеются файлы makefile или/и cmakeliststxt) библиотеку 64-бит...

173