doubling by copy
Question posted by: Klaus Ahrens
(Guest)
on
July 11th, 2006 03:55 PM
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
8
Answers Posted
Klaus Ahrens wrote:
Quote:
Originally Posted by
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
In article <e90f8u$d2i$1@news.datemas.de>,
"Victor Bazarov" <v.Abazarov@comAcast.netwrote:
Quote:
Originally Posted by
Klaus Ahrens wrote:
Quote:
Originally Posted by
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?
Daniel T. wrote:
Quote:
Originally Posted by
In article <e90f8u$d2i$1@news.datemas.de>,
"Victor Bazarov" <v.Abazarov@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());
}
Join Bytes! wrote:
Quote:
Originally Posted by
Daniel T. wrote:
Quote:
Originally Posted by
>In article <e90f8u$d2i$1@news.datemas.de>,
> "Victor Bazarov" <v.Abazarov@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);
Join Bytes! wrote:
Quote:
Originally Posted by
Daniel T. wrote:
Quote:
Originally Posted by
In article <e90f8u$d2i$1@news.datemas.de>,
"Victor Bazarov" <v.Abazarov@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:
[..]
Quote:
Originally Posted by
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.
Join Bytes! wrote:
Quote:
Originally Posted by
Join Bytes! wrote:
Quote:
Originally Posted by
>Daniel T. wrote:
Quote:
Originally Posted by
>>In article <e90f8u$d2i$1@news.datemas.de>,
>> "Victor Bazarov" <v.Abazarov@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:
[..]
Quote:
Originally Posted by
>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
In article <e90p8n$137$1@news.datemas.de>,
"Victor Bazarov" <v.Abazarov@comAcast.netwrote:
Quote:
Originally Posted by
Join Bytes! wrote:
Quote:
Originally Posted by
Join Bytes! wrote:
Quote:
Originally Posted by
Daniel T. wrote:
>In article <e90f8u$d2i$1@news.datemas.de>,
> "Victor Bazarov" <v.Abazarov@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:
[..]
Quote:
Originally Posted by
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?
Victor Bazarov wrote:
Quote:
Originally Posted by
Join Bytes! wrote:
Quote:
Originally Posted by
> Join Bytes! wrote:
Quote:
Originally Posted by
>>Daniel T. wrote:
>>>In article <e90f8u$d2i$1@news.datemas.de>,
>>> "Victor Bazarov" <v.Abazarov@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:
>[..]
Quote:
Originally Posted by
>>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
|
|
|
What is Bytes?
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 196,977 network members.
Top Community Contributors
|