Getting an iterator from a const vector.

Hello,

Quite a number of questions today! Anyway, why cannot I return an iterator from a const vector? The .begin isn't modifying the vector, so why is this?

Thank you,
Uni
vector<BIT>::iterator myFunc(const vector<BIT> &aVector){
	return aVector.begin();
}

Open in new window

LVL 3
Unimatrix_001Asked:
Who is Participating?
 
evilrixConnect With a Mentor Senior Software Engineer (Avast)Commented:
Because the vector is const so the iterator must be to. It's like trying to return a non-const pointer to a const object. If the compiler let you do this you might be able to change the object indirectly.

Code must be kept const correct.
int main()
{
	int const i = 0;
	int * pi = &i; // Error
	int const * cpi = &i; // Works
}

Open in new window

0
 
evilrixSenior Software Engineer (Avast)Commented:
^^^ try returning a vector::const_terator -- that should work fine.
0
 
Unimatrix_001Author Commented:
Okay thanks rix, I understand better now...
0
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
evilrixSenior Software Engineer (Avast)Commented:
>> ^^^ try returning a vector::const_terator -- that should work fine.
NB. The vector has an overloaded begin() function for a const object, that returns const_iterator.
#include <vector>
 
typedef std::vector<int> vec_t;
 
vec_t::const_iterator foo(vec_t const & v)
{
	return v.begin();
}
 
int main()
{
	vec_t v;
	foo(v);
}

Open in new window

0
 
Infinity08Commented:
evilrix was ahead of me again, but I'll post my reply anyway (because there's an other option - arguably less pretty, but still valid ;) )


>> why cannot I return an iterator from a const vector?

The const is basically a promise not to modify the vector inside the function. However, it also means that the vector is treated as if it were a non-modifiable (const) object.
A normal iterator allows the modification of whatever it points to. Since begin() returns such an iterator, you can't call begin() for a const vector, because the two don't match - ie. a non-const iterator for a const object doesn't make sense - so the compiler doesn't allow it.


You can either const_cast the reference :

        vector<BIT>::iterator myFunc(const vector<BIT> &aVector){
                return const_cast<vector<BIT>&>(aVector).begin();
        }

or you can return a const_iterator :

        vector<BIT>::const_iterator myFunc(const vector<BIT> &aVector){
                return aVector.begin();
        }
0
 
Unimatrix_001Author Commented:
Hm, that could be more useful/less risky than taking out the const... :)
0
 
Unimatrix_001Author Commented:
Hehe, cheers for 2nd view Infinity - it all helps. :)
0
 
Infinity08Commented:
Note that the reason why the const_cast isn't pretty, is because it would allow you to get a non-const iterator for an ACTUAL const vector. That can cause a world of trouble :)
0
 
evilrixSenior Software Engineer (Avast)Commented:
>> Since begin() returns such an iterator, you can't call begin() for a const vector
rather than calling...

 iterator begin();

you end up calling...

const_iterator begin() const;

http://www.sgi.com/tech/stl/Vector.html
iterator begin()  Container  Returns an iterator pointing to the beginning of the vector.  
const_iterator begin() const  Container  Returns a const_iterator pointing to the beginning of the vector.  

Open in new window

0
All Courses

From novice to tech pro — start learning today.