I have a vector std::vector. I would like to iterate the vector for finding a match, if found would like to return the pointer to the element as below:
const int * findint(std::vector <int> &v, int a)
{
std::vector<int>::const_iterator i1,i2;
i1 = v.begin();
i2 = v.end();
for(;i1 != i2;++i1) {
if(a== *i1) {
return(i1);
}
}
return(0);
}
This was compiling and working ok with GNU g++2.95.3 compiler but not compiling with GNU g++ 4.9.2 and giving the following error:
error: cannot convert 'std::vector<GenFld>::const_iterator {aka __gnu_cxx::__normal_iterator<const int*, std::vector<int> >}' to 'const int*' in return
[exec] return(i1);
Need help.
Unfortunately, there is no way to convert from an iterator directly to a pointer without dereferencing the iterator ( it[0] and &*it both dereference the iterator). As a result, the only way to convert iterators to pointers that is able to handle all valid iterators requires having access to the vector in question.
The most obvious form of an iterator is a pointer. A pointer can point to elements in an array and can iterate through them using the increment operator (++).
Use an iteratorAn iterator can be generated to traverse through a vector. vector<int>::iterator iter; An iterator is used as a pointer to iterate through a sequence such as a string or vector . The pointer can then be incremented to access the next element in the sequence.
This will solve your problem:
const int * findint(const std::vector <int> &v, int a){
auto i1 = v.cbegin();
auto i2 = v.cend();
for(;i1 != i2;++i1){
if(a == *i1){
return &*i1;
}
}
return nullptr;
}
Edit: Note that I changed iterators to cbegin
and cend
also the vector
is now passed as const
.
However, the right way to do it IMO (with respect to nathanoliver note):
auto it = std::find(v.cbegin(),v.cend(),value);
decltype(&*it) ptr;
if(it==v.cend()){
ptr = nullptr;
}
else{
ptr = &*it;
}
You have to be careful when using this. Pointers and Iterators may be invalid after any push_back
or insert
or erase
on the vector, for a comprehensive list see Iterator invalidation rules. If you want to keep a clue to reach some item later. and if you can guarantee that only adding to the back of the vector will happen, you may keep the index of the item using:
auto it = std::find(v.cbegin(),v.cend(),value);
size_t index;;
if(it==v.cend()){
//do something
}
else{
index = std::distance(v.cbegin(),it)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With