Ваш вопрос
Можем ли мы получить итератор, который фильтрует вектор из предиката в C ++?
в том смысле, в каком вас спрашивают, можно ответить только с помощью: Нет. На данный момент нет (C ++ 17). Согласно вашему требованию итератор должен будет хранить предикат и проверять его для каждой модификации позиции или для всего разыменовывающего материала. Т.е. перед любой разыменовкой нужно будет проверить предикат. Потому что другой код может изменить ваш std :: vector. Итератор должен постоянно проверять предикат. Также стандартные функции, такие как начало, конец, расстояние, были бы довольно сложными.
Таким образом, вы можете создать свой собственный итератор, производный от существующего итератора. Сохраните предикат и перегрузите большинство функций, чтобы позаботиться о предикате. Очень, очень сложно, много работы и, возможно, нет, то, что вы хотите иметь. Это был бы единственный способ получить точную требуемую функциональность.
Для обходных путей существует множество других возможных решений. Peolple покажет вам здесь.
Но если я прочитаю ваше заявление
«показывающий вид вектора»
тогда жизнь станет легче. Вы можете легко создать представление вектора, условно скопировав его с помощью std :: copy_if, как написано oblivion . Это, на мой взгляд, лучший ответ. Это не разрушительно. Но это снимок, а не исходные данные. Итак, это только для чтения. Кроме того, он не учитывает изменения исходного std :: vector после создания снимка.
Второй вариант, комбинация std :: remove_if и std :: erase, уничтожит исходные данные. Или лучше сказать, это сделает недействительными отфильтрованные данные. Вы также можете std :: copy_if ненужные данные в резервную область, std :: remove_if их, и в конце добавить их снова в вектор.
Все эти методы являются критическими, если исходные данные будут изменены.
Может быть, для вас лучше всего использовать стандартный std :: copy_if. Затем вы должны вернуть итератор копирования и работать с этим.
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
std::vector<int> testVector{ 1,2,3,4,5,6,7 }; // Test data
std::vector<int> testVectorView{}; // The view
// Create predicate
auto predForEvenNumbers = [](const int& i) -> bool { return (i % 2 == 0); };
// And filter. Take a snapshot
std::copy_if(testVector.begin(), testVector.end(), std::back_inserter(testVectorView), predForEvenNumbers);
// Show example result
std::vector<int>::iterator iter = testVectorView.begin();
std::cout << *iter << '\n';
return 0;
}
Пожалуйста, обратите внимание. Для больших std :: vectors это станет очень дорогим решением. , .