How to set all the values in a std::map
to the same value, without using a loop iterating over each value?
Using a loop is by far the simplest method. In fact, it’s a one-liner:[C++17]
for (auto& [_, v] : mymap) v = value;
Unfortunately C++ algorithm support for associative containers isn’t great pre-C++20. As a consequence, we can’t directly use std::fill
.
To use them anyway (pre-C++20), we need to write adapters — in the case of std::fill
, an iterator adapter. Here’s a minimally viable (but not really conforming) implementation to illustrate how much effort this is. I do not advise using it as-is. Use a library (such as Boost.Iterator) for a more general, production-strength implementation.
template <typename M>
struct value_iter : std::iterator<std::bidirectional_iterator_tag, typename M::mapped_type> {
using base_type = std::iterator<std::bidirectional_iterator_tag, typename M::mapped_type>;
using underlying = typename M::iterator;
using typename base_type::value_type;
using typename base_type::reference;
value_iter(underlying i) : i(i) {}
value_iter& operator++() {
++i;
return *this;
}
value_iter operator++(int) {
auto copy = *this;
i++;
return copy;
}
reference operator*() { return i->second; }
bool operator ==(value_iter other) const { return i == other.i; }
bool operator !=(value_iter other) const { return i != other.i; }
private:
underlying i;
};
template <typename M>
auto value_begin(M& map) { return value_iter<M>(map.begin()); }
template <typename M>
auto value_end(M& map) { return value_iter<M>(map.end()); }
With this, we can use std::fill
:
std::fill(value_begin(mymap), value_end(mymap), value);
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