Archived

This topic is now archived and is closed to further replies.

Graham11

STL vector class

Recommended Posts

Hi, What is the best method to allow a (C++) function access to elements obtained from a vector using an vector::iterator? Below, the first call to Test(int *) in main() fails to compile, while the second call is fine; I just think it looks a little unsafe. Any comments? Thanks, Graham
void Test(int *);

void main()
{
	vector<int> A;
	vector<int>::iterator Iter;

	for (Iter = A.begin(); Iter != A.end(); Iter++)
	{
		Test(Iter);		// error C2664: ''Test'' : cannot convert parameter 1 from ''std::vector<_Ty>::iterator'' to ''int *''

		Test(&(*Iter));	// OK.

	}
}

Share this post


Link to post
Share on other sites
Well vector iterators are often implemented in terms of pointers, but in this case they dont seem to be. Why not just make the function parameter take an std::vector::iterator? Why does it have to be an int*?

Share this post


Link to post
Share on other sites
Passing a copy of the iterator is slower but the safest way, as even if the vector changes, the iterator will still be valid (at least for the vector class, I think), whereas a pointer to the data might change if the data is rearranged for some reason. I''d try using a reference to the iterator:


void Test(vector::iterator &pos)
{
char buffer[10];
puts(itoa(*pos, buffer, 10));
}

Share this post


Link to post
Share on other sites
That does sounds like a good and correct technique, but it''s a shame that the function, Test(), is now constrained only to take the iterator, losing its flexibility. I guess the function could be overloaded.

Thanks very much,
Graham

Share this post


Link to post
Share on other sites
Well if you must have it as int*, your above solution is fine. Also note that main should have an int return type, not void.

Share this post


Link to post
Share on other sites
quote:
Original post by Graham11
... it''s a shame that the function, Test(), is now constrained only to take the iterator, losing its flexibility.


That''s what function templates are for, automatic overload generation.

template <class Iterator> void Test(Iterator it).

Share this post


Link to post
Share on other sites
quote:
Original post by Rian
Passing a copy of the iterator is slower but the safest way, as even if the vector changes, the iterator will still be valid (at least for the vector class, I think), whereas a pointer to the data might change if the data is rearranged for some reason.
Actually, vector iterators are not safe in this manner. A vector iterator does not really have many guarantees at all.
quote:
From MSDN Docs:
Vector reallocation occurs when a member function must grow the controlled sequence beyond its current storage capacity. Other insertions and erasures may alter various storage addresses within the sequence. In all such cases, iterators or references that point at altered portions of the controlled sequence become invalid.
Heh, I just realized this the hard way this week, on a pretty large project that was using pointers to elements in a vector quite a bit. I shoulda known better...




Most of the greatest evils that man has inflicted upon man have come through people feeling quite certain about something which, in fact, was false.

-Bertrand Russell, Unpopular Essays, "Ideas That Have Harmed Mankind"

Share this post


Link to post
Share on other sites
Uhmm...

void Test(int &);

void main() {
vector<int> A;
vector<int>::iterator Iter;

for(Iter = A.begin(); Iter != A.end(); ++Iter)
Test(*Iter);
}


-Markus-

Share this post


Link to post
Share on other sites
Thanks everyone.

I guess there is no magic bullet.

I didn''t know Fruny''s template technique; that''s very interesting.

Test(*Iter) doesn''t work.

Bye,
Graham

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
because your prototypes is void (int *) then you need to pass ADDRESS of Iter''s dereference:

Test(&(*Iter));

Share this post


Link to post
Share on other sites
quote:
Original post by Graham11
I didn''t know Fruny''s template technique; that''s very interesting.



Look at the contents of the <algorithm> header. That''s how the STL works.

Share this post


Link to post
Share on other sites