equal_range 和范围
equal_range and range for
在与我的学生讨论 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 的 return 类型是 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;
};
结合向多图(和其他)添加函数 API 到此结构中的 return 迭代器,而不是成对。
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; }
这些想法以前出现过吗?如果出现过,委员会的回应是什么?由于我没有看到的某些原因,它们只是不可行或不受欢迎吗?
(请注意,代码是在没有尝试编译或检查的情况下编写的,仅用于说明目的。这可能是错误的。并且它不包含类型检查以仅按应有的方式约束迭代器,因为这增加了复杂性没有用来解释这个想法。)
这就是boost::iterator_range
accomplishes, which was adopted into the range library TS as ranges::iterator_range
。该 TS 将在 C++17 之后的某个时间合并。
在与我的学生讨论 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 的 return 类型是 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;
};
结合向多图(和其他)添加函数 API 到此结构中的 return 迭代器,而不是成对。
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; }
这些想法以前出现过吗?如果出现过,委员会的回应是什么?由于我没有看到的某些原因,它们只是不可行或不受欢迎吗?
(请注意,代码是在没有尝试编译或检查的情况下编写的,仅用于说明目的。这可能是错误的。并且它不包含类型检查以仅按应有的方式约束迭代器,因为这增加了复杂性没有用来解释这个想法。)
这就是boost::iterator_range
accomplishes, which was adopted into the range library TS as ranges::iterator_range
。该 TS 将在 C++17 之后的某个时间合并。