Archived

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

STL vector class

This topic is 5172 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

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 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 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 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 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 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 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 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 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 on other sites
because your prototypes is void (int *) then you need to pass ADDRESS of Iter''s dereference:

Test(&(*Iter));

• 17
• 11
• 12
• 9
• 49
• Forum Statistics

• Total Topics
631394
• Total Posts
2999756
×