简体   繁体   English

为什么`std :: prev`不会在`std :: unordered_set`的迭代器中引发错误?

[英]Why `std::prev` does not fire an error with an iterator of `std::unordered_set`?

My question is related to the question linked below. 我的问题与下面链接的问题有关。 Bidirectional iterators in unordered_map? unordered_map中的双向迭代器?

Since I did not know std::unordered_set does not support bidirectional iterators, I happened to write a code similar to this one. 由于我不知道std::unordered_set不支持双向迭代器,因此我碰巧编写了与此类似的代码。

int main(){
    unordered_set<int> y{4};
    std::cout << *(std::prev(y.end())) << std::endl;
}

This program is COMPILED, but the last line of the code crashed the program. 该程序已编译,但是代码的最后一行使该程序崩溃。 Puzzled by that, I encountered the linked question. 对此感到困惑,我遇到了链接的问题。 However, I still don't understand why this program is compiled instead of throwing error messages while the code in the linked code(which is boost::unordered_set ) cannot be compiled. 但是,我仍然不明白为什么要编译此程序,而不是抛出错误消息,而无法编译链接代码(即boost::unordered_set )中的代码。 Could you clarify it? 你能澄清一下吗?

FYI, I am using Mingw64 with g++ 4.8.2 / Windows 7 / 64 bit environment. 仅供参考,我正在将Miningw64与g ++ 4.8.2 / Windows 7/64位环境一起使用。

std::prev only produces defined behavior for bidirectional iterators. std::prev仅为双向迭代器产生已定义的行为。


The GNU ISO C++ library (used by GCC 4.8.2) uses std::advance to implement std::prev , and std::advance itself is implemented like this: GNU ISO C ++库(由GCC 4.8.2使用)使用std::advance来实现std::prev ,而std::advance本身是这样实现的:

  • for random access iterators: 对于随机访问迭代器:

     __i += __n; 
  • for bidirectional iterators: 对于双向迭代器:

     if (__n > 0) while (__n--) ++__i; else while (__n++) --__i; 
  • for all other iterators: 对于所有其他迭代器:

     while (__n--) ++__i; 

So you can see that for an iterator of unordered_set , the function actually does not use the operator-- which produces the compiler error in the other question you linked. 因此,您可以看到,对于unordered_set的迭代器,该函数实际上不使用operator--在链接的另一个问题中会产生编译器错误。


It is your duty to make sure that an iterator passed to std::prev is bidirectional. 您有责任确保传递给std::prev的迭代器是双向的。 If that is not the case the C++ standard does not give you any guarantees what happens. 如果不是这种情况,则C ++标准不会为您提供任何保证。 GCC chooses to just silently ignore it, but it might as well crash your program. GCC选择只是默默地忽略它,但是它也有可能使您的程序崩溃。

std::prev可能使用std::advance ,其中,当参数(输入迭代器)不是双向的时,行为是不确定的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM