我注意到,如果传递的键小于地图的第一个键,则unordered_map :: equal_range upper_bound(第一个)返回end
#include <iostream>
#include <map>
#include <tr1/unordered_map>
using namespace std;
int main ()
{
{
std::map<char,int> mymap;
mymap['c'] = 60;
std::map<char,int>::iterator itup = mymap.equal_range('a').first;
std::cout << "map::itup " << itup->first << std::endl;
}
{
tr1::unordered_map<char, int> mymap;
mymap['c'] = 60;
mymap['d'] = 70;
tr1::unordered_map<char, int>::iterator itlo = mymap.equal_range('a').first;
tr1::unordered_map<char, int>::iterator itup = mymap.equal_range('a').second;
cout << "unordered_map::itup " << (itup == mymap.end() ? "END" : "NOT END") << std::endl;
cout << "unordered_map::itlo " << (itlo == mymap.end() ? "END" : "NOT END") << std::endl;
}
return 0;
}
输出为:
map::itup c
unordered_map::itup END
unordered_map::itlo END
请注意,地图和unordered_map的行为不同-出于任何原因,或者这是unordered_map中的问题?
谢谢, 亚历山大
答案 0 :(得分:2)
之所以会这样,是因为unordered_map
毫无顺序地是无序的。
有关equal_range
的要求,请参见§22.2.7[unord.req],Table 70:
返回:一个范围,其中包含所有具有与
k
等效的键的元素。 如果没有这样的元素,则返回make_pair(b.end(), b.end())
。
这与对有序关联容器(如std::map
)的要求不同,其中equal_range
是根据lower_bound
和upper_bound
定义的。
std::unordered_map
没有lower_bound
和upper_bound
,出于明显的原因。
答案 1 :(得分:2)
您要求一个范围,该范围包括您的unordered_map
中键为'a'
的所有元素。您的无序地图不包含此类元素。因此,范围为空。
map
情况也是如此。但是,表示此条件的方式因容器而异(尽管并非如此;请继续阅读)。容器std::map
和std::unordered_map
是不同的东西(因此它们具有不同的名称)。前者是有序的,而后者不是有序的,因此出于逻辑实现的原因,它的工作方式略有不同:
unordered_map
Return value
std::pair
包含一对定义所需范围的迭代器。如果没有这样的元素,则返回过去的迭代器(请参阅end()
)作为该对的两个元素。
map
Return value
std::pair
包含一对定义所需范围的迭代器:第一个指向不小于key
的第一个元素,第二个指向大于key
的第一个元素。 如果没有不小于key的元素,则返回过去(见end()
)迭代器作为第一个元素。同样,如果没有大于key
的元素,则返回过去的迭代器作为第二个元素。)
这种区别并不重要。在两种情况下,您都应该简单地迭代(first
,second
] 来检查元素(如果有)存在),就像使用任何迭代器范围一样。
在您的代码中,您没有检查在map
情况下返回的货币对中的两个货币对。如果您这样做,那么you'll find that first == second
(同样,表示一个空范围)。
您的map
代码有效地取消了对返回范围的“过去”迭代器的引用。
#include <iostream>
#include <map>
#include <unordered_map>
using namespace std;
int main ()
{
{
std::map<char,int> mymap;
mymap['c'] = 60;
std::map<char, int>::iterator itlo = mymap.equal_range('a').first;
std::map<char, int>::iterator itup = mymap.equal_range('a').second;
// This compares each range extent to the map's end, which is not really useful
cout << "map::itup " << (itup == mymap.end() ? "END" : "NOT END") << '\n';
cout << "map::itlo " << (itlo == mymap.end() ? "END" : "NOT END") << '\n';
// This examines the range itself
cout << "map range empty: " << (itlo == itup ? "YES" : "NO") << '\n';
cout << "map range size: " << std::distance(itlo, itup) << '\n';
}
{
std::unordered_map<char, int> mymap;
mymap['c'] = 60;
mymap['d'] = 70;
std::unordered_map<char, int>::iterator itlo = mymap.equal_range('a').first;
std::unordered_map<char, int>::iterator itup = mymap.equal_range('a').second;
// This compares each range extent to the map's end, which is not really useful
cout << "unordered_map::itup " << (itup == mymap.end() ? "END" : "NOT END") << std::endl;
cout << "unordered_map::itlo " << (itlo == mymap.end() ? "END" : "NOT END") << std::endl;
// This examines the range itself
cout << "unordered_map range empty: " << (itlo == itup ? "YES" : "NO") << '\n';
cout << "unordered_map range size: " << std::distance(itlo, itup) << '\n';
}
}
// Output:
//
// map::itup NOT END
// map::itlo NOT END
// map range empty: YES
// map range size: 0
// unordered_map::itup END
// unordered_map::itlo END
// unordered_map range empty: YES
// unordered_map range size: 0