views:

3659

answers:

4

So, I wrote a bunch of code that accesses elements in an stl vector by index[], but now I need to copy just a chunk of the vector. It looks like vector.insert(pos, first, last) is the function I want... except I only have first and last as ints. Is there any nice way I can get an iterator to these values?

+38  A: 

Try this:

vector<Type>::iterator nth = v.begin() + index;
dirkgently
Oh! I didn't know you could do that. That's awesome, thanks :)
Mark
Generally, you can use the same arithmetic with STL iterators than with pointers. They are designed to be exchangeable when using STL algorithms.
Vincent Robert
+34  A: 

way mentioned by @dirkgently ( v.begin() + index ) nice and fast for vectors

but std::advance( v.begin(), index ) most generic way and for random access iterators works constant time too.

EDIT
differences in usage:

std::vector<>::iterator it = ( v.begin() + index );

or

std::vector<>::iterator it = v.begin();
std::advance( it, index );

added after @litb notes.

bb
doesn't std::advance require a non-const iterator as the first argument?
goldPseudo
according this - http://www.sgi.com/tech/stl/advance.html - no.
bb
you can use std::advance with const and non-const iterators
bb
bb, that page you linked says it requires a non-const reference. so better do vector<T>::iterator it = v.begin(); advance(it, index); instead
Johannes Schaub - litb
where you see this requirement?
bb
i wasn't clear with my wording. i mean it has a non-const reference as a parameter. it so requires lvalues as arguments.
Johannes Schaub - litb
yes. iterator will copied. but usualy it is not problem.
bb
@goldPseudo: on my stl from vc 2008, next code compiled w/o errors. std::vector< size_t >::const_iterator it = v.begin(); std::advance( it, 5 );
bb
bb, see: template<typename T> void f(T f(1); /* bug, doesn't compile */ . you need a f<const int>(1); or just say int x; f(x);
Johannes Schaub - litb
you should not trust msvc in that regard. it has a non-standard extension that makes it accept this kind of thing, nevertheless all other compilers behave standard and refuse it.
Johannes Schaub - litb
yes, I agree, msvc compiling - was fast check. that about you saying: it works for const_iterator, for iterator ( by my link, and standard ), and it acepting non-const reference, because it will change this reference.
bb
I think the problem is confusion over the meaning of "const": advance() will happily work on a const_iterator<T>, which is a mutable iterator that refers to a const element of type T; it won't work on an iterator object which is itself const (i.e. "const iterator<T>" or "iterator<T> const").
j_random_hacker
A: 

Actutally std::vector are meant to be used as C tab when needed. (C++ standard requests that for vector implementation , as far as I know - replacement for array in Wikipedia) For instance it is perfectly legal to do this folowing, according to me:

int main()
{

void foo(const char *);

sdt::vector<char> vec;
vec.push_back('h');
vec.push_back('e');
vec.push_back('l');
vec.push_back('l');
vec.push_back('o');
vec.push_back('/0');

foo(&vec[0]);
}

Of course, either foo must not copy the address passed as a parameter and store it somewhere, or you should ensure in your program to never push any new item in vec, or requesting to change its capacity. Or risk segmentation fault...

Therefore in your exemple it leads to

vector.insert(pos, &vec[first_index], &vec[last_index]);
yves Baumes
Makes me wonder why they decided to abstract away to iterators if they're just pointers... they're essentially "hiding" these capabilities.
Mark
For consitency ? As it would allow you to easily remove vector instance for any other kind of container in your code so.
yves Baumes
sellibitze
+4  A: 

Or you can use std::advance

vector<int>::iterator i = L.begin();
advance(i, 2);
TimW