简体   繁体   中英

Algorithm name?: Concatenate the ranges returned by a function applied to each element of a range

Maybe I'm missing something. Is there a function in <algorithm> that does this? If not, what would you call it? It seems like a particular flavor of transform-reduce that is so specific it needs a name:

template <typename Iter, typename OutIter, typename Fn>
void transformed_concatenated(Iter beg, Iter end, OutIter out, Fn f) {
    for (; beg != end; ++beg) {
        for (auto& x : f(*beg)) {
            *out++ = std::move(x);
        }
    }
    return out;
}

That is, if I do

const std::vector<int> input { 0, 1, 2, 3 };
const auto f = [](int n) { return std::vector<int>(n, n * 2 + 1); };
std::vector<int> result;
transformed_concatenated(input.begin(), input.end(), std::back_inserter(result), f);

I would get 3, 5, 5, 7, 7, 7 .

Something like it could be done with std::transform_reduce , but I feel like it loses something.

With the ranges and views introduced in C++20, you could write:

std::ranges::copy(input 
                  | std::views::transform(f) 
                  | std::views::join, 
                  std::back_inserter(result));

Here's a demo .


Note that your function f is incorrect. It needs to be

const auto f = [](int n) { return std::vector<int>(n, n); };
                                               // ^____^

to get the desired output 1 2 2 3 3 3 . If you use braces to construct the vector, you'll get a vector of 2 elements, both with the value n , and the output will be 1 1 2 2 3 3 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM