samedi 29 avril 2023

Why do associative containers have an erase overload with non-const iterator argument?

C++11 changed std::vector::erase to take a const_iterator instead of an iterator. The same thing applies to std::deque and std::list, while std::forward_list came in C++11 with erase_after, which also takes a const_iterator.

In contrast, std::set::erase kept its iterator overload and C++11 simply added the const_iterator one. The same thing applies to all associative containers: std::map, std::multiset, and std::multimap all kept the pre-C++11 iterator overload while std::unordered_set, std::unordered_map, std::unordered_multiset, and std::unordered_multimap all were introduced with both iterator and const_iterator overloads.

In fact, for all four set classes, iterator and const_iterator may very well be the same type.

So why the discrepancy? In addition to the inconsistency with the non-associative containers, there is also an inconsistency with the range erase overloads, which were all changed with C++11 to take a pair of const_iterators instead of a pair of iterators. Since an iterator must be convertible to a const_iterator, there is no need to have all four possible combinations of parameters for the range erase. Similarly, there is no need to have "all two combinations" for the single-value erase, so why keep the iterator overload?

Aucun commentaire:

Enregistrer un commentaire