简体   繁体   中英

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?

Since I did not know std::unordered_set does not support bidirectional iterators, I happened to write a code similar to this one.

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. Could you clarify it?

FYI, I am using Mingw64 with g++ 4.8.2 / Windows 7 / 64 bit environment.

std::prev only produces defined behavior for bidirectional iterators.


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:

  • 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.


It is your duty to make sure that an iterator passed to std::prev is bidirectional. If that is not the case the C++ standard does not give you any guarantees what happens. GCC chooses to just silently ignore it, but it might as well crash your program.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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