Reputation: 7513
I am not crystal clear about pointer and iterator, especially in the case of constructing vector from an array.
From the description about vector, it says
// the iterator constructor can also be used to construct from arrays:
int myints[] = {16,2,77,29};
std::vector<int> fifth (myints, myints + sizeof(myints) / sizeof(int) );
in primary, it is:
#include <vector>
int arr[ARR_LEN] = { /* Array elements */ };
std::vector<int> vecInt(arr, arr + ARR_LEN);
does it use the following constructor?
template <class InputIterator>
vector (InputIterator first, InputIterator last,
const allocator_type& alloc = allocator_type());
If so, then here, is a pointer (for array) treated into an random access iterator, then as input iterator? How does the compiler do this? Considering iterators from other containers, what is the type of this iterator, e.g. "array[int]"::iterator?
int arr[N] = {};
for (int i= 0; i<N; i++) {}
instead of the above, can I do something like as follows?
for (ItorType it=arr; it!=arr+N; ++it) { ... }
Upvotes: 0
Views: 634
Reputation: 88017
template <class InputIterator>
vector (InputIterator first, InputIterator last,
const allocator_type& alloc = allocator_type());
The compiler will use this constructor simply because it a two argument constructor with the same type for both arguments.
It doesn't have to be that the arguments are iterators. For instance if you write
vector<int> x(3.0, 1.0);
the compiler will try to use the same constructor (which would then lead to compile errors because doubles can't be used like iterators).
Upvotes: 1
Reputation: 254751
does it use the following constructor?
Yes.
If so, then here, is a pointer (for array) treated into an random access iterator, then as input iterator?
Yes.
How does the compiler do this?
Concepts like InputIterator
are informal specifications of how a type must behave; to be an InputIterator
, it must support indirection (*it
) to access a value, and increment (++it
and it++
) to move to the next value. To be a RandomAccessIterator
, it must support these operations, plus a few more such as addition and subtraction. Pointers meet these requirements, so can be used wherever an iterator is required.
Considering iterators from other containers, what is the type of this iterator, e.g. "array[int]"::iterator?
You'd use a pointer, int*
, to iterate over an array, int[]
. When used as a function argument (as here), or used in arithmetic (such as arr+N
), the array is automatically converted to a pointer to its first element.
instead of the above, can I do something like as follows?
Yes. ItorType
would be the corresponding pointer type, int*
. In C++11, we have begin
and end
functions to get the beginning and end of any range including arrays:
for (auto it = std::begin(arr); it != std::end(arr); ++it)
and also range-based loops:
for (int i : arr)
Upvotes: 2
Reputation: 749
Yes, it uses aforementioned constructor and treats pointer as random access iterator. Since all RandomAccessIterators also are InputIterators (see here). Compiler can do this cause Iterator classes defines valid operators on itself in terms of static interfaces. No matter how they implemented and actually means. Only type correctness and interface correctness plays their roles.
You could typedef int * ItorType
and your last sample would compiled and worked very well.
Upvotes: 1
Reputation: 154035
The iterator template arguments are not specific class. In fact, the names have no real impact on the compilation process. Instead, they refer to specific concepts which specify the methods available for a specific iterator. Any RandomAccessIterator also has to be an InputIterator: the RandomAccessIterator concept is a refinement of the InputIterator concept.
The compiler really just passes these arguments, in your case pointers, through. Pointers implement the RandomAccessIterator concept, i.e., they can be readily used with the std::vector<...>
constructor you quoted. BTW, the proper way to write this initialization is
std::vector<int> vecInt(std::begin(arr), std::end(arr));
The function templates begin()
and end()
were added to the latest version of C++ and deduce the size of statically sized arrays. Both approaches used to determine the size in your example are problematic in some ways.
Upvotes: 5