Declaring iterators

D

desktop

I am not sure I quite understand the use of iterators. I have this int
array:

int a[] = {1,2,3,4,5}

I would now like to make an iterator to the first and last element:

std::iterator<int> iter;
iter = a;

but this does not compile.

If I instead choose to make an iterator on a vector it works:

#include <vector>

std::vector<int> vecIter;


why is it not possible to make an iterator to an int array (besides from
the obvious: int* iter = a)?
 
O

osmium

desktop said:
I am not sure I quite understand the use of iterators. I have this int
array:

int a[] = {1,2,3,4,5}

I would now like to make an iterator to the first and last element:

std::iterator<int> iter;

That construct is for the STL and arrays are not part of the STL. If you
want to implement the *properties* of an iterator, go ahead and write one.
But you can't use the one from STL.
 
D

desktop

osmium said:
desktop said:
I am not sure I quite understand the use of iterators. I have this int
array:

int a[] = {1,2,3,4,5}

I would now like to make an iterator to the first and last element:

std::iterator<int> iter;

That construct is for the STL and arrays are not part of the STL. If you
want to implement the *properties* of an iterator, go ahead and write one.
But you can't use the one from STL.

Ok so if I want a generic function that works correctly on both int
arrays and vectors, I have to write a new iterator?

How do I check if an iterator has the right type?

I have read that you don't declare an iterator type like Forward, its up
to the function that you implement to make sure that it will satisfy the
properties of a Forward iterator.

That means that it is only by inspecting a function you can see which
iterators are supported. The compiler will not generate any error if I
have an iterator "iter" and then type:

--iter

because you cannot declare a Forward iterator explicitly. Or am I
missing something?
 
O

osmium

desktop said:
Ok so if I want a generic function that works correctly on both int arrays
and vectors, I have to write a new iterator?

How do I check if an iterator has the right type?

I have read that you don't declare an iterator type like Forward, its up
to the function that you implement to make sure that it will satisfy the
properties of a Forward iterator.

That means that it is only by inspecting a function you can see which
iterators are supported. The compiler will not generate any error if I
have an iterator "iter" and then type:

This will probably not prove helpful but I have the general feeling you are
trying to make a silk purse out of a sow's ear. As I see it you want a
seamless way to handle arrays and vectors. But arrays are not containers.
They are not even classes. Containers have properties like front, back,
size and on and on till the head swims. Arrays don't have those things. If
you want to iterate through arrays, then do so. But it won't be an array
any more because an array doesn't have something as elementary as size
specified. IOW, as I see it, you are on the road to inventing the C++
vector.
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

osmium said:
desktop said:
I am not sure I quite understand the use of iterators. I have this int
array:

int a[] = {1,2,3,4,5}

I would now like to make an iterator to the first and last element:

std::iterator<int> iter;

That construct is for the STL and arrays are not part of the STL. If you
want to implement the *properties* of an iterator, go ahead and write one.
But you can't use the one from STL.

Ok so if I want a generic function that works correctly on both int
arrays and vectors, I have to write a new iterator?

No, you make a parametrized function.
How do I check if an iterator has the right type?

An iterator is not a type, it's a concept. The compiler checks so that
the type you provided fulfils the requirements of the concept.
I have read that you don't declare an iterator type like Forward, its up
to the function that you implement to make sure that it will satisfy the
properties of a Forward iterator.

The compiler does.
That means that it is only by inspecting a function you can see which
iterators are supported. The compiler will not generate any error if I
have an iterator "iter" and then type:

--iter

because you cannot declare a Forward iterator explicitly. Or am I
missing something?

The compiler will refuse to compile the code if the iterator you
supplied does not support the -- operation.


Iterators is an abstract concept that lives in the minds of the
programmers, there is no one type that is an iterator or from which all
iterators inherits. When using iterators the compiler checks so that the
type used as an iterator provides all the functionality required and
will fail to compile the program if it does not. As long as the type
supplied do provide the functionality it *is* an iterator, regardless of
what type it has.

Consider the following code:

#include <numeric>
#include <iostream>
#include <vector>

int main()
{
int arr[] = { 1, 2, 3, 4, 5 };
std::vector<int> vec;
vec.push_back(1);
vec.push_back(2);
vec.push_back(3);
vec.push_back(4);
vec.push_back(5);

int arrSum = std::accumulate(arr, arr + 5, 0);
int vecSum = std::accumulate(vec.begin(), vec.end(), 0);

std::cout << "Array: " << arrSum << std::endl;
std::cout << "Vector: " << vecSum << std::endl;
}

Here we call the same function (std::accumulate) with two different
types of iterators, in the first we use int* as iterator and in the
second std::vector<int>::iterator. Those two types have nothing in
common, except that parts of their interfaces are the same: you can
dereference them by using *, you can move them one step forward using
++, and so on. And since they both have the "right" functionality in
their interface we can use them as iterators.

Perhaps it will be easier to understand if I show you how accumulate is
implemented (or rather how I would implement it):

template<class Iter, class Val>
Val accumulate(Iter begin, Iter end, Val v)
{
while (begin != end)
{
v += *begin;
++begin;
}
return v;
}

From this you can see that accumulate places three requirements on the
type used as iterator, you shall be able to test two instance of the
type for inequality (!=), you shall be able to dereference an instance
of the type (*), and you shall be able to increment an instance (++). It
also places one requirement on the type you accumulate the values of,
you shall be able to add-assign (+=).
 
J

Jim Langston

desktop said:
I am not sure I quite understand the use of iterators. I have this int
array:

int a[] = {1,2,3,4,5}

I would now like to make an iterator to the first and last element:

std::iterator<int> iter;
iter = a;

but this does not compile.

If I instead choose to make an iterator on a vector it works:

#include <vector>

std::vector<int> vecIter;


why is it not possible to make an iterator to an int array (besides from
the obvious: int* iter = a)

From what Erik says, I gather that int* iter = a; IS an iterator. I.E. You
should be able to pass iter to the standard templates that require an
iterator.
 
J

James Kanze

I am not sure I quite understand the use of iterators. I have this int
array:
int a[] = {1,2,3,4,5}
I would now like to make an iterator to the first and last element:
std::iterator<int> iter;
iter = a;
but this does not compile.

Obviously. The template std::iterator requires two arguments,
and doesn't do what you want anyway. (Despite its name, it
isn't an iterator, but simply a convenience class to provide a
certain number of useful typedef's for any iterator you might
choose to define.)
If I instead choose to make an iterator on a vector it works:
#include <vector>
std::vector<int> vecIter;
why is it not possible to make an iterator to an int array (besides from
the obvious: int* iter = a)?

Are you saying that if you include <vector>, the line:
std::iterator< int > iter ;
compiles? It shouldn't.

Each container type provides its own iterator. Containers in
the STL provide it as a member type (or typedef), e.g.:
std::vector< int >::iterator iter = v.begin();
C style arrays provide it in the form of a pointer; the
constraints on iterators were intentionally designed so that
pointers (into an array) would be iterators. The result is that
you do declare the iterators differently:
std::vector< int >::iterator iter1 ;
int* iter2 ;
What's the problem with that?
 
J

James Kanze

I am not sure I quite understand the use of iterators. I have this int
array:
int a[] = {1,2,3,4,5}
I would now like to make an iterator to the first and last element:
std::iterator<int> iter;
iter = a;
but this does not compile.
If I instead choose to make an iterator on a vector it works:
#include <vector>
std::vector<int> vecIter;
why is it not possible to make an iterator to an int array (besides from
the obvious: int* iter = a)
From what Erik says, I gather that int* iter = a; IS an iterator. I.E. You
should be able to pass iter to the standard templates that require an
iterator.

That's certainly true.

In this case, the key is to realize that iterator isn't a type,
but a concept. A type (any type) can be used as an iterator if
it meets the constraits. Both std::vector<int>::iterator and
int* meet the constraints of an iterator, so both can be used
anywhere an iterator is required. Neither int nor
std::vector<int> meet the constraints, so neither can be used
when an iterator is required. (There is a wierd special case in
the case of things like:
std::vector< int > v( 10, 42 ) ;
Formally, function overload resolution results in this calling
the two iterator form of the constructor, with the iterator type
instantiated with int. The standard requires the implementation
to cause the instantiation to behave as if the programmer had
written:
std::vector< int > v( static_cast< size_t >( 10 ), 42 ) ;
however. The iterator argument is not considered an iterator.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top