6 ms·
This is a poor understanding of what an iterator is. For one, the iterator of a std::vector<T> is not a T*, it's a std::vector<T>::iterator and you are welcome
by Kranar 5y ago
This is a poor understanding of what an iterator is. For one, the iterator of a std::vector<T> is not a T*, it's a std::vector<T>::iterator and you are welcome to verify that the following assertion fails for all T:
static_assert(std::is_same_v<T\*, std::vector<T>::iterator>)
Link provided below for convenience [1].
Furthermore just like a cat is animal does not imply an animal is a cat, a pointer being an iterator does not imply that an iterator is a pointer and holding such a confusing thought is the source of many bugs and poor C++ code. An iterator not only represents a form of indirection to an object, it also represents traversal through a collection of values.
unordered_map guarantees that the objects it stores will remain alive until the unordered_map is destroyed or the object is removed from the map. However, unordered_map, as the name once again suggests, does not provide any guarantee about the ordering of objects. Hence, if you have an iterator to an object owned by such a map, and you add or remove objects to that map, the iterator becomes invalid not because the object the iterator references gets destroyed, but because the iterator loses information about where it's located within the unordered collection.
For further information, please review the following link [2], specifically the quote "References and pointers to either key or data stored in the container are only invalidated by erasing that element, even when the corresponding iterator is invalidated.".
[1] https://godbolt.org/z/Y5f4d74Kb https://godbolt.org/z/Y5f4d74Kb
[2] https://en.cppreference.com/w/cpp/container/unordered_map https://en.cppreference.com/w/cpp/container/unordered_map
- saagarjha 5y agoYou're being far more patronizing than is necessary here, especially because the parent poster was correct in iterators originating out of a being a generalization over pointers, although not in their latter statement. But, while implementation defined, a vector iterator must behave identically to a pointer, and your assertion fails in both Clang and GCC not for any interesting reason but more because they wrap the pointer into a class for what I understand to be better encapsulation and earlier detection of nonportable code, not because pointers are somehow unfit to do the job of std::vector<T>::iterator. It so happens that iterators have become a useful way to generically iterate over noncontiguous containers as well, but it is very clear that they are "logically" meant to mirror the usage of a pointer (down to the operators you use to work with them) and suggesting that holding this opinion is a sign of inadequacy is condescending.
- Kranar 5y ago>because the parent poster was correct in iterators originating out of a being a generalization over pointers And an animal is a generalization of a cat, but that doesn't mean an animal is a cat. What is true of a particular doesn't have to be true of the general. > But, while implementation defined, a vector iterator must behave identically to a pointer No it does not. MSVC implements a vector iterator with additional runtime safety guarantees in DEBUG mode and while those guarantees are not mandatory as per the standard, they are fully in compliance, so saying they have to behave identically is patently false as MSVC's behavior is a superset of the behavior provided by a pointer. > suggesting that holding this opinion is a sign of inadequacy is condescending. If you care about writing correct code, then do not mix the very concept of pointers, arrays, references, and iterators with one another. They are all related to one another but have very important differences to the point that calling them literally identical to one another is a sign of inadequate understanding. It happens far too often and inevitably leads to poor code, bugs, and a fundamentally poor understanding of what these things represent conceptually.
- saagarjha 5y agoFirst of all, calm down. Consider that the people you are talking to may not be idiots. Second of all, nobody is saying that pointers, arrays, references, and iterators are identical in general. They are clearly related concepts but differ in fundamental ways. However, my point was that a vector iterator needs to behave like a pointer would and can in fact be implemented as a naked pointer. Pointing to MSVC's implementation having safety checks does not change that fact, because pointing to what an implementation does on undefined behavior is clearly out of scope when discussing specified behavior. I'm not going to bring address sanitizer into this discussion to show how pointers can actually be a superset of "pointer behavior" because that would just be irrelevant. The fact remains that iterators were originally meant to act like pointers, and in many cases still do. Believing this does not mean I have a poor understanding of the language.
- Kranar 5y agoNot knowing something does not make you an idiot, there are tons of things I don't know about C++ and I make tons of mistakes. However, not knowing something and doubling down on that lack of knowledge by defending something that is wrong because you don't like the tone of the person correcting you about it is highly problematic and suggests you are prioritizing your own sensitivity on the issue and protecting your own ego instead of taking the opportunity to learn something new. >Second of all, nobody is saying that pointers, arrays, references, and iterators are identical in general. The comment I replied to said, and I quote: "I mean, literally. The iterator of an std::vector<T> is a T*." That is what I originally replied to before you felt it necessary to interject yourself into the conversation to police my tone. >However, my point was that a vector iterator needs to behave like a pointer would and can in fact be implemented as a naked pointer. No, you said it is required that they behave identically, which is false, once again, I quote you: "a vector iterator must behave identically to a pointer" There is no such requirement that they behave identically, and there is a demonstrable example of a compiler where they do not behave identically. Furthermore your talk about it being undefined behavior is false on the basis that in general, two pointers of type T* may compare with one another, for example the following is valid: auto v1 = new int(); auto v2 = new int(); v1 == v2; // This is valid. However, this is undefined behavior. auto v1 = vector_a.begin(); auto v2 = vector_b.begin(); v1 == v2; // This is undefined behavior. Only iterators to the same vector may be compared, which is not true of pointers. >Believing this does not mean I have a poor understanding of the language. I did not say you have a poor understanding of the language as a whole, I said if you believe that an iterator to a vector is identical to pointer as you have claimed, then you have a poor understanding of iterators. I stand by that statement and I would suggest that you not be so sensitive about being wrong about a corner case of the language and instead simply accept this to be a fact, learn something new, and move on with your day. I learn new things about C++ all the time, sometimes from polite people, sometimes from jerks, it's all the same because what matters is the learning. Something doesn't become wrong just because the person who told it to you said it in a way you disapprove of. Having said that, all the best to you Sir and thank you for engaging in this discussion. I have said all I think is appropriate given the topic.
- einpoklum 5y agoOk, as you and others have pointed out - the iterator of a vector doesn't have to be T: https://en.cppreference.com/w/cpp/container/vector https://en.cppreference.com/w/cpp/container/vector It _may_ be a T, or anything satisfying LegacyRandomAccessIterator. > just like a cat is animal does not imply an animal is a cat, It's not "just like" that. Among other differences between the pairs of concepts: The concept of an animal didn't arise as a generalization of cats.