Gigi Hofleitner
Gigi Hofleitner

Reputation: 125

Print address of iterator

Why is it not possible to change the cout line with following in order to get the address of the iterator?

#include <iostream>
#include <string>
#include <vector>

using namespace std;

int main (int argc, const char* argv[]) {
    vector<int> inputs = {15, 20, 10, 5, 19};
    vector<int>::iterator i;
    i = inputs.begin();
    cout << *i << endl;
    return 0;
}

Above example of iterator. Clear.

cout << i << endl;

Upvotes: 3

Views: 2146

Answers (2)

anastaciu
anastaciu

Reputation: 23792

It's not possible because there is no overload for operator<< that takes vector<>::iterator as its second argument. If you want to print the address of the iterator object, you'd need &i.

Or you could overload it yourself:

std::ostream &operator<<(std::ostream &os, const std::vector<int>::iterator &i) {
  os << &i;
  return os;
}

Live sample

Upvotes: 2

user5550963
user5550963

Reputation:

Lets have a little C++ lesson.

&i is address of a variable *i is deference of pointer i is variable itself

So if you have, i is variable:

int i = 5;
cout << "print variable i: " << i << "\n";
cout << "print address of variable i: " << &i << "\n";

If you have:

int* i = new int();
*i = 5;
cout << i << "\n";

would give you address where 5 is stored.

cout << &i << "\n";

would give you an address where pointer to 5 is stored.

cout << *i << "\n";

would print 5.

For printing int element you can override io operators:

// here `&i` is reference to iterator 
//      (address that you cannot change)
std::ostream &operator<<(std::ostream &os, 
                         const std::vector<int>::iterator &i)
{
    os << *i;
    return os;
}

If you go to cppreference says that iterator.bet Now in C++ you have derived types and iterator and vector are some of them.

There are questions: What does it mean to print iterator? Here is wiki definition

In computer programming, an iterator is an object that enables a programmer to traverse a container, particularly lists. Various types of iterators are often provided via a container's interface.

In essence it does not make sense to print iterator itself (in your case i), thus io stream for iterators is not implemented.

Another reason for not implementing IO stream, like it is case for vector (iterators as well), is that they are template classes, meaning that you can have custom type.

Take this example:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

class myNumb {
public:
    myNumb (int i) : num (i) {}

private:
    int num;
};

int main (int argc, const char* argv[]) {
    vector<myNumb> inputs = {15, 20, 10, 5, 19};
    vector<myNumb>::iterator i;
    i = inputs.begin();
    cout << inputs[i] << endl;
    return 0;
}

If you have:

class myCoord {
public:
   myCoord (double lo, double la) :
                longitude (lo), latitude(la) {}
private:
   double longitude, latitude;
}

So what if we have this:

class city {
public:
    city (string n, long p) :
         name (n), population (p)
private:
    string name;
    long population;
    myCoord location;
}

So in essence it makes more sense to override is stream for these derived types so you can use them when printing element of array, vector or list or map or custom some other container.

Upvotes: 0

Related Questions