In order to avoid mutable containers / states I currently wonder what's the closest thing to construct a const
STL container from some input, e.g.
const vector<int> input = {2, 13, 7, 1};
What I'd like to do is something like this:
const auto transformed = generate_from<vector<string>>(
input.begin(), input.end(), to_string);
do_something(transformed);
While the approach you find the most would create a mutable object and modify it (what I'd like to avoid):
vector<string> bad_mutable_container;
for (const auto & elem : input) {
bad_mutable_container.push_back(to_string(input[elem]));
};
do_something(bad_mutable_container);
C++11 and newer provide std::generate
and std::generate_n
but they operate on a mutable object, so they don't solve my problem:
vector<string> bad_mutable_container(input.size());
generate_n(bad_mutable_container.begin(), input.size(), [&input, n=0] () mutable {
return to_string(input[n++]);
});
What you can do now is encapsulate that code in a function/lambda which gives you const-ness but also noisy boilerplate code:
const auto transformed = [&input] {
vector<string> bad_mutable_container;
for (const auto & elem : input) {
bad_mutable_container.push_back(to_string(elem));
};
return bad_mutable_container;
} ();
do_something(transformed);
I've expected to find at least some constructor for e.g. std::vector
which I can use like this:
const auto transformed = vector<string>(input.size(), [&input, n=0] () mutable {
return to_string(input[n++]);
});
What would be the most modern C++ish approach to this today and why?
With boost::transform_iterator
, you may do:
auto to_string_fun = [](const auto& e){ return std::to_string(e); };
const std::vector output(boost::transform_iterator(input.begin(), to_string_fun),
boost::transform_iterator(input.end(), to_string_fun));
Demo
With range-v3, you may do:
const std::vector<std::string> output = input
| ranges::view::transform([](int e){ return std::to_string(e); });
Demo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With