Daily bit(e) C++. std::views::adjacent_transform
Daily bit(e) C++ #209, новая функция из C++23 – представление применений N-арного вызываемого объекта, вызываемого для идущих последовательно элементов: std::views::adjacent_transform
.
std::view::adjacent_transform
в C++23 – это представление, которое создает элементы путем непрерывного применения предоставленного N-арного вызываемого объекта к каждой последовательной группе из N элементов.
Этот же функционал можно имитировать, комбинируя std::views::adjacent
и std::views::transform
, однако это менее эффективно и более громоздко.
#include <ranges>
#include <vector>
#include <iostream>
int main()
{
std::vector<int> data{5,1,2,4,3};
auto med3 = [](int a, int b, int c){
if (a >= b)
{
if (b >= c) return b;
if (a >= c) return c;
return a;
}
else
{
if (c >= b) return b;
if (a >= c) return a;
return c;
}
};
auto medians = data | std::views::adjacent_transform<3>(med3);
// medians == {2, 2, 3}
for (auto e : medians)
std::cout << e << " ";
std::cout << "\n";
// То же, что и предыдущее, но без промежуточного кортежа:
auto medians_twostep = data | std::views::adjacent<3> |
std::views::transform([&](auto&& e) {
return std::apply(med3, e);
});
// medians_twostep == {2, 2, 3}
for (auto e : medians_twostep)
std::cout << e << " ";
std::cout << "\n";
// Имитирование алгоритма разности смежных элементов.
// Попарная специализация эквивалентна adjacent_transform<2>.
auto adjacent_difference = data |
std::views::pairwise_transform(std::minus<>{});
// adjacent_difference == {4, -1, -2, 1}
for (auto e : adjacent_difference)
std::cout << e << " ";
std::cout << "\n";
}
Открыть пример на Compiler Explorer.
Вывод примера:
2 2 3
2 2 3
4 -1 -2 1