Closed GeorgiiFirsov closed 2 years ago
Это все есть в range. И даже намного больше. godbolt
#include <fmt/format.h>
#include <range/v3/view/concat.hpp>
#include <range/v3/view/iota.hpp>
#include <range/v3/view/transform.hpp>
#include <range/v3/view/zip.hpp>
#include <vector>
namespace rv = ranges::views;
int main() {
std::vector<int> vi{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::vector<std::string> const vs{"hello", "goodbye", "hello", "goodbye"};
for (auto [n, s] : rv::zip(vi, vs)) {
fmt::print("n: {} | s: {}\n", n, s);
}
fmt::print("\n=====\n\n");
for (auto [n, s] : rv::zip(rv::iota(4), vs)) {
fmt::print("n: {} | s: {}\n", n, s);
}
fmt::print("\n=====\n\n");
for (auto [n, s] :
rv::zip(rv::iota(1), rv::concat(vs, vi | rv::transform([](auto i) {
return std::to_string(i);
})))) {
fmt::print("n: {} | s: {}\n", n, s);
}
}
zip приняли в C++23 в https://wg21.link/P2321
chain приняли в стандарт под именем join
#include <iostream>
#include <ranges>
int main()
{
using namespace std::literals;
auto v = { std::views::iota(1, 5), std::views::iota(5, 10) };
auto jv = std::ranges::join_view(v);
// 1 2 3 4 5 6 7 8 9
for (int const e : jv) std::cout << e << ' ';
std::cout << '\n';
}
Суть
В целом сама идея, думаю, и из заголовка ясна. Предлагаю добавить такие функции, как
zip
иchain
.Первая возвращает адаптер, итератор которого содержит кортеж из ссылок/значений (этот момент вообще требуется дополнительно обдумать, как такое лучше реализовать, возможно в комментах напишу продолжение), полученных из соответствующих переданным контейнерам/диапазонам итераторов. При этом если один диапазон короче другого, то следует итерироваться до конца самого короткого. Хотя в целом тут можно добавить вариант с проверкой равенства длин диапазонов.
Вторая же "ставит" один диапазон за другим, позволяя по окончании первого перейти к элементам второго. Внутренние типы диапазонов должны совпадать или хотя бы быть приводимыми друг к другу или к общему родителю (если ссылки или указатели).
Стоит отметить, что ограничиваться двумя аргументами не представляется рациональным - данные концепции нетрудно обобщаются на произвольное количество диапазонов.
Примеры
Думаю, примеров можно подобрать много и во многих областях, когда требуется проитерироваться по нескольким последовательностям примерно следующим образом (концепт):
Реализация
Реализацию
zip
можно найти в бусте.chain
же в целом не представляет большой сложности в реализации.