我对代码有查找问题,并且不确定迭代器测试的正确解释。问题是:我有一个集合并使用upper_bound进行查找,然后想要找到下一个最低元素。像这样:
#include <iostream>
#include <set>
#include <algorithm>
void exploreSet(std::set<int> &int_set, int key);
int main()
{
std::set<int> int_set { 5, 10, 12, 17, 19 };
exploreSet(int_set, 15);
exploreSet(int_set, 4);
return 0;
}
void exploreSet(std::set<int> &int_set, int key)
{
auto it = int_set.upper_bound(key);
if ( it==int_set.end() )
{
std::cout << "Nothing found.\n";
}
else
{
std::cout << "Found " << *it << ".\n";
// Now find the next lowest value -- how?
auto it_back = it;
--it_back;
if ( it_back==int_set.end() )
{
std::cout << "Nothing prior.\n";
}
else
{
std::cout << "Prior value: " << *it_back << ".\n";
}
}
}
使用std = c ++ 14:
在gcc 4.9.2上运行此结果的结果输出Found 17.
Prior value: 12.
Found 5.
Nothing prior.
这很有效。但为什么呢?
在通过upper_bound获得的迭代器上向后比较时,与std :: set :: end()进行比较是否正确?为什么或为什么不呢?
答案 0 :(得分:2)
不,这是不正确的。递减等于begin()
的迭代器是未定义的行为。见[bidirectional.iterators] / 1,表110:
<强>表达式强>
--r
断言/注意前/后条件
pre:s
存在r == ++s
帖子:r
可以取消引用。
因此,正确的方法是将it
与int_set.begin()
进行比较:
// Now find the next lowest value -- how?
if ( it == int_set.begin() )
{
std::cout << "Nothing prior.\n";
}
else
{
auto it_back = it;
--it_back;
std::cout << "Prior value: " << *it_back << ".\n";
}
那就是说,我建议将std::set<int, std::greater<int>>
与lower_bound
一起使用:
template <typename Set>
void exploreSet(const Set& int_set, int key) {
auto it = int_set.lower_bound(key);
if (it == int_set.end())
std::cout << "Nothing found.\n";
else
std::cout << "Found " << *it << ".\n";
}
int main() {
std::set<int, std::greater<int>> int_set { 5, 10, 12, 17, 19 };
exploreSet(int_set, 15);
exploreSet(int_set, 4);
}