Каков правильный способ обернуть объект в соответствующую монаду/аппликатив с помощью Range-v3?

Предположим, что при таком диапазоне

std::vector<int> v{1, 4, 7, 2};

Я хочу создать другой диапазон, в котором все четные числа повторяются столько раз, сколько их значение, тогда как все нечетные числа остаются неизменными.

Возможным решением является следующее:

#include <iostream>
#include <range/v3/view/join.hpp>
#include <range/v3/view/transform.hpp>
#include <range/v3/view/repeat_n.hpp>
#include <vector>

using namespace ranges::views;

auto f = [](auto x){
    return (x % 2) ? repeat_n(x,1) : repeat_n(x,x);
};

int main() {
    std::vector<int> v{1, 4, 7, 2};
    auto w = v | transform(f) | join;
    for (auto i : w)
        std::cout << i << std::endl;
}

Однако использование repeat_n(x,1) только для того, чтобы обернуть x в одноэлементный диапазон, мне кажется немного неуклюжим. Есть ли какая-то специальная функция в Range-v3 для этого?


person Enlico    schedule 19.02.2021    source источник
comment
ranges::views::single будет таким, но его тип отличается от repeat_n, поэтому вы можете не просто используйте его в ?:. Может быть, return repeat_n(x, (x % 2) ? 1 : x) может быть чище?   -  person Artyer    schedule 19.02.2021
comment
@Artyer, я понимаю, что ты имеешь в виду, и проблема в том, что я хочу, чтобы эти две вещи были одного типа. Наверное, я слишком упростил вопрос. Я удалю его сейчас и, возможно, напишу новый, где более подробно объясню свои потребности.   -  person Enlico    schedule 19.02.2021
comment
@Artyer, я задал более подробный вопрос здесь, если вы хотите взглянуть на это.   -  person Enlico    schedule 19.02.2021