By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,305 Members | 1,614 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,305 IT Pros & Developers. It's quick & easy.

doubling by copy

P: n/a
hi all,

is it legal to double the content of a vector c by

copy(c.begin(), c.end(), back_inserter(c));

when ensuring before

c.reserve(2*c.size());

???

best regards

k ahrens
Jul 11 '06 #1
Share this Question
Share on Google+
8 Replies


P: n/a
Klaus Ahrens wrote:
is it legal to double the content of a vector c by

copy(c.begin(), c.end(), back_inserter(c));

when ensuring before

c.reserve(2*c.size());

???
I don't see any problem with it. If no reallocation happens (and
'reserve' should take care of that), all iterators stay valid, and
you're just copy-constructing elements after the previous end.
The only one thing I'd worry about is that the 'end' changes, so
there can be an implementation in which the object returned by
'c.end()' can keep changing when you push_back (moving target).

If you need to simply grow the vector by copying its contents at
the end, why not try

c.reserve(..
c.insert(c.end(), c.begin(), c.end());

it might be slightly faster.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jul 11 '06 #2

P: n/a
In article <e9**********@news.datemas.de>,
"Victor Bazarov" <v.********@comAcast.netwrote:
Klaus Ahrens wrote:
is it legal to double the content of a vector c by

copy(c.begin(), c.end(), back_inserter(c));

when ensuring before

c.reserve(2*c.size());

???

I don't see any problem with it. If no reallocation happens (and
'reserve' should take care of that), all iterators stay valid, and
you're just copy-constructing elements after the previous end.
The only one thing I'd worry about is that the 'end' changes, so
there can be an implementation in which the object returned by
'c.end()' can keep changing when you push_back (moving target).
How could you have a moving target? c.end() is evaluated only once
before entering the copy function, isn't it?
Jul 11 '06 #3

P: n/a
Daniel T. wrote:
In article <e9**********@news.datemas.de>,
"Victor Bazarov" <v.********@comAcast.netwrote:

How could you have a moving target? c.end() is evaluated only once
before entering the copy function, isn't it?
Yes, if the copy() function is written properly. The following copy()
function never ends:

#include <vector>
#include <iostream>

using namespace std;

void copy( vector<int&v,
const vector<int>::iterator &b,
const vector<int>::iterator &e){
while(b!=e){
cout<<"size="<<v.size()<<endl;
v.push_back(*b);
}
}

int main(){
vector<intv;
v.push_back(1);
v.push_back(2);
copy(v,v.begin(), v.end());
}

Jul 11 '06 #4

P: n/a
jo******@gmail.com wrote:
Daniel T. wrote:
>In article <e9**********@news.datemas.de>,
"Victor Bazarov" <v.********@comAcast.netwrote:

How could you have a moving target? c.end() is evaluated only once
before entering the copy function, isn't it?

Yes, if the copy() function is written properly. The following copy()
function never ends:

#include <vector>
#include <iostream>

using namespace std;

void copy( vector<int&v,
const vector<int>::iterator &b,
const vector<int>::iterator &e){
while(b!=e){
cout<<"size="<<v.size()<<endl;
v.push_back(*b);
}
}
However, according to 25.2.1, that can't happen, as the iterators are
passed by value, not by reference. The footprint for std::copy is as
follows:

template<class InputIterator, class OutputIterator>
OutputIterator copy(InputIterator first, InputIterator last,
OutputIterator result);
Jul 11 '06 #5

P: n/a
jo******@gmail.com wrote:
Daniel T. wrote:
In article <e9**********@news.datemas.de>,
"Victor Bazarov" <v.********@comAcast.netwrote:

How could you have a moving target? c.end() is evaluated only once
before entering the copy function, isn't it?

Yes, if the copy() function is written properly. The following copy()
function never ends:
[..]
void copy( vector<int&v,
const vector<int>::iterator &b,
const vector<int>::iterator &e){
while(b!=e){
cout<<"size="<<v.size()<<endl;
v.push_back(*b);
}
Oops, sorry, of course that doens't end. I thought that the iterator by
reference would change, but clearly it doesn't with the standard vector
class.

I guess if the c.end() in the original example were to return a
reference to an internal iterator, then a problem would occur.

Jul 11 '06 #6

P: n/a
jo******@gmail.com wrote:
jo******@gmail.com wrote:
>Daniel T. wrote:
>>In article <e9**********@news.datemas.de>,
"Victor Bazarov" <v.********@comAcast.netwrote:

How could you have a moving target? c.end() is evaluated only once
before entering the copy function, isn't it?

Yes, if the copy() function is written properly. The following copy()
function never ends:
[..]
>void copy( vector<int&v,
const vector<int>::iterator &b,
const vector<int>::iterator &e){
while(b!=e){
cout<<"size="<<v.size()<<endl;
v.push_back(*b);
}

Oops, sorry, of course that doens't end. I thought that the iterator
by reference would change, but clearly it doesn't with the standard
vector class.

I guess if the c.end() in the original example were to return a
reference to an internal iterator, then a problem would occur.
Even if 'copy' accepts an iterator by value, it's still possible for
that iterator to get the reference to the container, and perform some
kind of lookup based on the "real" (floating) end of the container when
'==' is used on it...

All those examples are of course beyond common sense, I guess.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jul 11 '06 #7

P: n/a
In article <e9**********@news.datemas.de>,
"Victor Bazarov" <v.********@comAcast.netwrote:
jo******@gmail.com wrote:
jo******@gmail.com wrote:
Daniel T. wrote:
In article <e9**********@news.datemas.de>,
"Victor Bazarov" <v.********@comAcast.netwrote:

How could you have a moving target? c.end() is evaluated only once
before entering the copy function, isn't it?

Yes, if the copy() function is written properly. The following copy()
function never ends:
[..]
void copy( vector<int&v,
const vector<int>::iterator &b,
const vector<int>::iterator &e){
while(b!=e){
cout<<"size="<<v.size()<<endl;
v.push_back(*b);
}
Oops, sorry, of course that doens't end. I thought that the iterator
by reference would change, but clearly it doesn't with the standard
vector class.

I guess if the c.end() in the original example were to return a
reference to an internal iterator, then a problem would occur.

Even if 'copy' accepts an iterator by value, it's still possible for
that iterator to get the reference to the container, and perform some
kind of lookup based on the "real" (floating) end of the container when
'==' is used on it...

All those examples are of course beyond common sense, I guess.
Personally I would consider that an implementation error. Does the
standard say one way or the other?
Jul 11 '06 #8

P: n/a
Victor Bazarov wrote:
jo******@gmail.com wrote:
>jo******@gmail.com wrote:
>>Daniel T. wrote:
In article <e9**********@news.datemas.de>,
"Victor Bazarov" <v.********@comAcast.netwrote:

How could you have a moving target? c.end() is evaluated only once
before entering the copy function, isn't it?
Yes, if the copy() function is written properly. The following copy()
function never ends:
[..]
>>void copy( vector<int&v,
const vector<int>::iterator &b,
const vector<int>::iterator &e){
while(b!=e){
cout<<"size="<<v.size()<<endl;
v.push_back(*b);
}
Oops, sorry, of course that doens't end. I thought that the iterator
by reference would change, but clearly it doesn't with the standard
vector class.

I guess if the c.end() in the original example were to return a
reference to an internal iterator, then a problem would occur.

Even if 'copy' accepts an iterator by value, it's still possible for
that iterator to get the reference to the container, and perform some
kind of lookup based on the "real" (floating) end of the container when
'==' is used on it...

All those examples are of course beyond common sense, I guess.

V
While I can't find anything that prevents end() from being implemented
in such a way, I do believe that a version of copy() that couldn't
handle that would be non-conforming, since the complexity requirements
are "Exactly last - first assignments."

--
Alan Johnson
Jul 12 '06 #9

This discussion thread is closed

Replies have been disabled for this discussion.