In the following code, I get an error if I type either of the following two
cout << "value of it: " << vec.begin() << endl;
cout << "value of it: " << it << endl;
But if I write following, I do not get error:
cout << "value of it: " << it-Vec.begin() << endl;
Why is that?
#include <iostream>
#include <vector>
#include <algorithm>
using std::cout;
using std::endl;
using std::vector;
int main(){
vector<int> Vec{1, 20, 3, 14, -5, 6, 1, 8, 0, 7 };
std::sort(Vec.begin(), Vec.end());
int find_Y = 3;
auto it = std::lower_bound(Vec.begin(), Vec.end(), find_Y);
cout << "value of it: " << it << endl; // This gives error!!
cout << "Value of *it: " << *it << endl;
cout << "Index of Y: " << it - Vec.begin() << endl;
}
You may think of an iterator as a pointer. Unless you define cout operator << on an iterator, you get a compiler error.
Vec.begin()
returns an iterator that points to the first element of Vec.
auto it = std::lower_bound
also returns an iterator.
So, it is not surprising that cout << iterator gives an error:
error: no match for 'operator<<' (operand types are 'std::basic_ostream<char>' and '__gnu_cxx::__normal_iterator<int*, std::vector<int> >')
You can safely dereference Vec.begin()
to see the the value, Vec[0]
.
You can safely dereference the lower_bound
return iterator provided that the iterator is not Vec.end()
.
But if I write following, I do not get error:
cout << "value of it: " << it - Vec.begin() << endl;
Just like in C's pointer arithmetic, you can subtract two iterators. See @Jason R's answer here:
How does subtracting X.begin() return the index of an iterator?
Suppose it
points to Vec.begin()
, then the difference is 0. If it
points to (Vec.begin() + 1), then the difference is 1.
If you are unfamiliar with C pointer arithmetic, please read section, "Pointer arithmetics" here: https://cplusplus.com/doc/tutorial/pointers/
Here is your modified program to illustrate the above points:
#include <iostream>
#include <vector>
#include <algorithm>
using std::cout;
using std::endl;
using std::vector;
int main(){
vector<int> Vec{1, 20, 3, 14, -5, 6, 1, 8, 0, 7 };
std::sort(Vec.begin(), Vec.end());
for( auto val:Vec) { cout << val << " "; } std::cout << std::endl; // -5 0 1 1 3 6 7 8 14 20
cout << "*Vec.begin() = " << *Vec.begin() << "; *(Vec.end() - 1) = " << *(Vec.end() - 1) << endl; // -5 20
int find_Y = 3;
auto it = std::lower_bound(Vec.begin(), Vec.end(), find_Y);
// Deference it if allowed
if( it != Vec.end() )
{
// cout << "value of it: " << it << endl; // This gives error!!
cout << "value of *it: " << *it << endl; // This fixes error.
cout << "Index of Y: " << it - Vec.begin() << endl;
}
else
{
cout << "find_y exceeds max value in Vec" << endl;
cout << "Index of Y: " << it - Vec.begin() << endl;
}
}
Output:
-5 0 1 1 3 6 7 8 14 20
*Vec.begin() = -5; *(Vec.end() - 1) = 20
value of *it: 3
Index of Y: 4
You can change values of find_Y to, say 21, to execute the else condition.