Daily bit(e) C++. std::views::adjacent_transform

Добавлено 8 августа 2023 в 21:50

Daily bit(e) C++ #209, новая функция из C++23 – представление применений N-арного вызываемого объекта, вызываемого для идущих последовательно элементов: std::views::adjacent_transform.

Daily bit(e) C++. 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

Теги

C++ / CppC++23Daily bit(e) C++STL / Standard Template Library / Стандартная библиотека шаблоновПрограммирование

На сайте работает сервис комментирования DISQUS, который позволяет вам оставлять комментарии на множестве сайтов, имея лишь один аккаунт на Disqus.com.

В случае комментирования в качестве гостя (без регистрации на disqus.com) для публикации комментария требуется время на премодерацию.