I just discovered that at one point, the C++11 draft had std::begin
/std::end
overloads for std::pair
that allowed treating a pair of i
I think the 2009 paper "Pairs do not make good ranges" by Alisdair Meredith is at least part of the answer. Basically, many algorithms return pairs of iterators that are actually not guaranteed to be valid ranges. It seems they removed the support for pair
from the for-range loop for this reason. However, the proposed solution has not been fully adopted.
If you know for certain that some pair of iterators really represents a valid range then you could wrap them into a custom type which offers begin()/end() member functions:
template
struct iter_pair_range : std::pair {
iter_pair_range(std::pair const& x)
: std::pair(x)
{}
Iter begin() const {return this->first;}
Iter end() const {return this->second;}
};
template
inline iter_pair_range as_range(std::pair const& x)
{ return iter_pair_range(x); }
int main() {
multimap mm;
...
for (auto& p : as_range(mm.equal_range(42))) {
...
}
}
(untested)
I agree this is a bit of a wart. Functions which return valid ranges (like equal_range) should say so using an appropriate return type. It's a bit embarrasing that we have to manually confirm this via something like as_range
above.