return result of "copy", "remove_copy"

J

Jess

Hello,

The C++ reference says the return result of "copy" is an output
iterator. I'm wondering how I can assign the returned iterator to
some other iterator. I tried

int main(){
string s("abcdefg");
vector<char> v;
vector<char>::iterator k = copy(s.begin(),s.end(),back_inserter(v));
return 0;
}

because for "copy", the returned iterator should point to the last
element in the destination range. However, the code above couldn't
compile. What's my problem? Moreover, does "copy" return the iterator
pointing to the last element or one past the last element?

As for "remove_copy", does it return the iterator pointing to one past
the last element? How can I assign the return result to some
iterator? I think it should be the same as for "copy".

Thanks,
Jess
 
N

Neelesh Bodas

Hello,

The C++ reference says the return result of "copy" is an output
iterator. I'm wondering how I can assign the returned iterator to
some other iterator. I tried

int main(){
string s("abcdefg");
vector<char> v;
vector<char>::iterator k = copy(s.begin(),s.end(),back_inserter(v));

copy will return the back_insert_iterator

std::back_insert_iterator<std::vector<char> > k = copy(s.begin(),
s.end(), back_insertor(v));

Moreover, does "copy" return the iterator
pointing to the last element or one past the last element?

last element
As for "remove_copy", does it return the iterator pointing to one past
the last element?


no. last element.
 
J

James Kanze

The C++ reference says the return result of "copy" is an output
iterator.

Sort of. The C++ reference says that the return result of
"copy" has the type OutputIterator, where OutputIterator is the
second argument of the template. This can be any type which
meets the constraints of an output iterator. In normal use, it
will be the type which the compiler deduces for the third
argument of copy.
I'm wondering how I can assign the returned iterator to
some other iterator. I tried
int main(){
string s("abcdefg");
vector<char> v;
vector<char>::iterator k = copy(s.begin(),s.end(),back_inserter(v));
return 0;
}
because for "copy", the returned iterator should point to the last
element in the destination range. However, the code above couldn't
compile. What's my problem?

The type of the OutputIterator argument isn't
std::vector< char >::iterator. It's (in this case)
std::back_insertion_iterator< std::vector< char > >. Which
isn't convertible into std::vector< char >::iterator.

The usual use of this return value would be in functions like:

template< typename InputIter1,
typename InputIter2,
typename OutputIter >
OutputIter
copy2( InputIter1 begin1, InputIter1 end1,
InputIter2 begin2, InputIter2 end2,
OutputIter dest )
{
return std::copy( begin2, end2, std::copy( begin1, end2,
dest ) ) ;
}

(I'm sure you can think of more useful examples, but this is the
first thing that comes to my mind.)

In non-template code (where you have names like
"std::back_insertion_iterator< std::vector< char > >", rather
than OutputIter), it's a bit awkward if you need to use a
variable, rather than just passing it to another (template)
function, but the next addition of the standard will help
greatly here, allowing something like:

auto k = std::copy( s.begin(), s.end(),
std::back_inserter( v ) ) ;

and letting the compiler work it out.
Moreover, does "copy" return the iterator
pointing to the last element or one past the last element?

One past the end, as always. Everything in C++ works with
half-open intervals, so any reference to the "end" of a range is
one past the last element.
As for "remove_copy", does it return the iterator pointing to one past
the last element? How can I assign the return result to some
iterator? I think it should be the same as for "copy".

Exactly the same.

Note that when using a back_insertion_iterator, the concept of
"one past the last element" is a bit weak. Just think of it as
an iterator which will allow further access immediately after
the last element inserted (provided access there would otherwise
be legal).
 
A

Andrew Koenig

last element

I think not. The typical implementation does something similar to this:

template<class In, class Out>
Out copy(In begin, In end, Out dest)
{
while (begin != end)
*out++ = *begin++;
return out;
}

so what it returns is an iterator referring to the point after the last
element of the result.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,268
Latest member
AshliMacin

Latest Threads

Top