Обсуждая multimap
со своими студентами, я заметил небольшое изменение, которое могло убрать часть шаблона, и мне было интересно, предлагал ли кто-нибудь это комитету по стандартизации, и если да, то каков был ответ.
Канонический метод перебора равного диапазона (взято с cplusplus.com):
// multimap::equal_range
#include <iostream>
#include <map>
int main ()
{
std::multimap<char,int> mymm;
mymm.insert(std::pair<char,int>('a',10));
mymm.insert(std::pair<char,int>('b',20));
mymm.insert(std::pair<char,int>('b',30));
mymm.insert(std::pair<char,int>('b',40));
mymm.insert(std::pair<char,int>('c',50));
mymm.insert(std::pair<char,int>('c',60));
mymm.insert(std::pair<char,int>('d',60));
std::cout << "mymm contains:\n";
for (char ch='a'; ch<='d'; ch++)
{
std::pair <std::multimap<char,int>::iterator,std::multimap<char,int>::iterator> ret;
ret = mymm.equal_range(ch);
std::cout << ch << " =>";
for (std::multimap<char,int>::iterator it=ret.first; it!=ret.second; ++it)
std::cout << ' ' << it->second;
std::cout << '\n';
}
return 0;
}
В этом случае вы не можете напрямую использовать диапазон, основанный на цикле for, потому что тип возврата equal_range — это pair<multimap<K,V>::iterator, multimap<K,V>::iterator>
. Однако простая структура-оболочка должна позволять это:
template <typename T>
struct abstract_collection {
abstract_collection(pair<T, T> its)
: m_begin(its.first),
m_end(its.second) {}
abstract_collection(T begin, T end)
: m_begin(begin),
m_end(end) {}
T begin() const { return m_begin; }
T end() const { return m_end; }
T m_begin;
T m_end;
};
В сочетании с добавлением функции в multimap (и другие) API для возврата итераторов в этой структуре, а не в паре.
template<typename K, typename V, typename C, typename A>
auto multimap<K, V, C, A>::equal_range_c(K const& k) -> abstract_collection<iterator> {
return equal_range(k);
}
Или, альтернативно, перегрузка версии std::begin
и std::end
, которая использует пару итераторов, также должна работать:
template <typename T>
T begin(pair<T, T> p) { return p.first; }
template <typename T>
T end(pair<T, T> p) { return p.second; }
Появлялись ли эти идеи раньше, и если да, то какова была реакция комитета? Они просто неработоспособны или нежелательны по какой-то причине, которую я не вижу?
(Обратите внимание, что код был написан без попыток компилировать или проверять только в демонстрационных целях. Это, вероятно, неправильно. И он не содержит проверки типов, чтобы ограничить итераторы только так, как должно, поскольку это добавило сложности, которая не служила для поясните мысль)
begin()
иend()
в пространство именstd
является поведением undefined. - person Barry   schedule 02.05.2016