Does Using a Pointer as a Container Iterator Violate the Standard
Asked Answered
C

3

6

Angew made a comment that a vector using a raw pointer as it's iterator type was fine. That kinda threw me for a loop.

I started researching it and found that the requirement for vector iterators was only that they are "Random Access Iterators" for which it is explicitly stated that pointers qualify:

A pointer to an element of an array satisfies all requirements

Is the only reason that compilers even provide iterators to vector for debugging purposes, or is there actually a requirement I missed on vector?

Carbonization answered 25/1, 2017 at 13:38 Comment(5)
More likely for consistency with the rest of the standard library. template <class Container> void doStuff(const Container& c) { for (Container::iterator i = c.begin(); i != c.end(); ++i) { ... } } A template like this doesn't care what type of container you use as long as it provides iterator, begin and end.Calash
@Calash I don't understand what you're saying? Obviously the container must return iterators. I just didn't think that returning raw pointers was reasonable. Are you addressing that statement, or something else?Carbonization
The tricky part is the ADL-associated namespaces of std::vector<T>::iterator. Pointers do not have std as an associated namespace. The Standard does not require iterators to have std as an associated namespace, though.Swainson
@Swainson I'm always misunderstanding ADL lookup, but why would using a pointer here be an issue?Carbonization
@JonathanMee: Can you swap two std::vector<T>::iterators with unqualified swap(it1, it2) ?Swainson
M
3

§ 24.2.1

Since iterators are an abstraction of pointers, their semantics is a generalization of most of the semantics of pointers in C++. This ensures that every function template that takes iterators works as well with regular pointers.

So yes, using a pointer satisfies all of the requirements for a Random Access Iterator.

std::vector likely provides iterators for a few reasons

  1. The standard says it should.

  2. It would be odd if containers such as std::map or std::set provided iterators while std::vector provided only a value_type* pointer. Iterators provide consistency across the containers library.

  3. It allows for specializations of the vector type eg, std::vector<bool> where a value_type* pointer would not be a valid iterator.

Mccarron answered 25/1, 2017 at 13:59 Comment(2)
You're hinging the "The standard says it should" on the statement "iterators are an abstraction of pointers" right?Carbonization
"The standard says it should" explains why there are iterators for vectors. Numbers 2 and 3 are just two possible reasons why the standard says it should.Mccarron
C
2

My 50 cents:

Iterators are generic ways to access any STL container. What I feel you're saying is: Since pointers are OK as a replacement of iterators for vectors, why are there iterators for vectors?

Well, who said you can't have duplicates in C++? Actually it's a good thing to have different interfaces to the same functionality. That should not be a problem.

On the other hand, think about libraries that have algorithms that use iterators. If vectors don't have iterators, it's just an invitation to exceptions (exceptions in the linguistic since, not programming sense). Every time one has to write an algorithm, he must do something different for vectors with pointers. But why? No reason for this hassle. Just interface everything the same way.

Citreous answered 25/1, 2017 at 13:56 Comment(3)
What operations would you be referring to that must be done differently between iterators and pointers? I can't actually think of any.Carbonization
@JonathanMee I think his point is, that iterators are there just to let vector have the same interfaces available, as other classes - to prevent needing special treatment of vector class, by anyone who prefers working with iterators over pointers for everything else, for example.Cushman
@Cushman Can you give me an example of how you'd work differently with an iterator than you would a pointer? This is a great answer if pointers must be treated differently or function differently than iterators. But if they provide identical operators, and have identical behavior then this is not a great answer. (I've been using pointers interchangeably with iterators for years.)Carbonization
I
2

What those comments are saying is that

template <typename T, ...>
class vector
{
public:
    typedef T* iterator;
    typedef const T* const_iterator;
    ...
private:
    T* elems; // pointer to dynamic array
    size_t count;
    ...
}

is valid. Similarly a user defined container intended for use with std:: algorithms can do that. Then when a template asks for Container::iterator the type it gets back in that instantiation is T*, and that behaves properly.

So the standard requires that vector has a definition for vector::iterator, and you use that in your code. On one platform it is implemented as a pointer into an array, but on a different platform it is something else. Importantly these things behave the same way in all the aspects that the standard specifies.

Irradiation answered 25/1, 2017 at 14:16 Comment(1)
I believe this is the only answer that addresses the OP's real underyling question.Hako

© 2022 - 2024 — McMap. All rights reserved.