Что-то ощущение, что вопрос из серии "как я сам недотумкал", но...
Есть генератор (чисел, но лучше объектов). В идеале - как-то возвращает, что закончил генерировать (хорошо бы, чтоб можно было и istream_iterator
передать, и лямбду, скажем...), но - скрепя сердце - согласен даже на просто количество. Дальше - есть предикат, который в сам генератор не зашивается (а если зашивается - то мы точно не можем сказать заранее, сколько значений будет сгенерировано!)
Их хочется отфильтровать и отправить куда-то.
Частями делается просто - скажем, generate_n
в какой-то вектор (через back_inserter
), потом - copy_if
с предикатом - скажем, в ostream_iterator
.
Написать собственный код еще проще :)
Но хочется извратиться - через STL и без дополнительного хранения в контейнере. В идеале - одной строкой (один вложенный вызов).
Ощущение, что крутится что-то такое рядом, но что-то никак не дается...
Вот пример кода:
vector<int> v(1000);
generate(v.begin(),v.end(),[](){.....});
copy_if(v.begin(),v.end(),[](){.....},
ostrim_iterator<int>(cout,"\n"));
Как сделать это же БЕЗ дополнительного вектора? Если количество генерируемых объектов может быть очень велико?
generate_n
не годится по двум причинам: в нем нет предиката и я заранее не знаю, сколько будет сгенерировано объектов. Если я перенесу предикат прямо в генератор - как объяснить, что все сгенерировано и пора выходить из алгоритма? Разве что с помощью исключения, но это - некорректное с проектной точки зрения решение.
Свой код выглядит примерно так:
int n;
ostrim_iterator<int> os(cout,"\n");
while([&n](){ return true; /* false по окончании генерации*/ })
{
if (pred(n)) *os++ = n;
}
Т.е. пока генерируется, просто проверяем предикатом и отправляем через итератор.
Еще раз подчеркиваю - мне не задачу решить, мне просто интересно, как ее решить, оставаясь в рамках стандартной библиотеки, и можно ли это вообще? Казалось бы, цепочка
Генератор -> Фильтр -> Выход
не должна быть редкостью, так что стандартная библиотека должна бы содержать ее решение?
Update
Придумался вариант - написание итератора от генератора. Т.е. с каждым ++
этот итератор возвращает вновь сгенерированное значение. Тогда хватит вообще обычного copy_if
. Нет такого стандартного адаптера, превращающего генератор в итератор?...
возможно стоит поиграться с rangeV3 эрика нилберта, все-таки это когда то станет стандартом: https://ericniebler.github.io/range-v3/ код нет возможности проверить, но думаю копать примерно так:
//взято из тестов
auto ns = view::generate([]() mutable {
static int N;
return ++N;
});
auto rng = ns | view::take_while([](int i) { return i < 5; }); //сюда нужно вставить ваш предикат
//ну и отправляем rng в std::cout:
ranges::for_each(myRanges, [](auto const& r) { std::cout << r << '\n'; });
//либо вроде даже так, не помню точно:
std::cout<<rng;
если нужны примеры, то есть в тестах у него: https://github.com/ericniebler/range-v3/tree/master/test
Виртуальный выделенный сервер (VDS) становится отличным выбором
Как получить значение из тега Output?Это ползунокКак можно реализовать получение значения
Есть форма регистрации и в ней ипнут, который на вход принимает email пользователя:
Есть элемент span на форме, в onmousedown которого производится его удаление и вызов некоего событияВ этом событии отправляется Ajax-запрос к серверу
Не получается динамически подгружать модульДелаю по документации раздел: require