2015-04-06 53 views
2

我有一个查找问题的代码,并不确定正确的解释迭代器测试。问题是这样的:我有一个set并使用upper_bound进行查找,然后想要查找下一个最低元素。像这样:C++ std :: set 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"; 
     } 
    } 
} 

所得上的gcc 4.9.2与STD运行此= C++ 14的输出:

Found 17. 
Prior value: 12. 
Found 5. 
Nothing prior. 

这工作。但为什么?

当通过upper_bound获得的迭代器向后进行比较时,与std :: set :: end()进行比较是否正确?为什么或者为什么不?

+0

// 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一起lower_bound'?在一个'set'上它直接到你想要的。 –

+0

@MooingDuck只有当你使用'std :: greater'作为集合的比较器 –

+0

@AntonSavin:我对你的评论感到非常困惑。他的算法似乎显示的最大值小于或等于'std :: less'命令的容器中的给定键,这正是'lower_bound'在默认情况下所做的。我误解了什么? –

回答

2

不,这是不正确的。减量迭代器等于begin()是未定义的行为。参见[bidirectional.iterators]/1,表110:

表达
--r
断言/音符前置/后置条件
预:存在s使得r == ++s
post:r是可解引用的。

所以正确的方法是比较itint_set.begin():你为什么不能简单地使用`

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); 
} 
+0

谢谢。这回答了这个问题。 –

相关问题