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
.