C++ Online Reference

A

arnuld

Hi all,

you folks have seen how wrongly I understood std::remove() algorithm. I
got that understanding from here:

http://www.cppreference.com/cppalgorithm/remove.html

which simply says, "The remove() algorithm removes all of the elements
....."

fortunately comp.lang.c++ told me that is not true and Stroustrup on my
Desk also confirmed that. Sadly, Nicolai's book is not availale in my
country, So i looked for some correct online reference and I found this
one is frequently recommended:

http://www.dinkumware.com/cpp.aspx

but somone here also recommended the http://www.cppreference.com/ which
has quite wrong information. So I want to know, How is Dinkumware
Documentation ?




-- arnuld
http://lispmachine.wordpress.com
 
A

anon

arnuld said:
Hi all,

you folks have seen how wrongly I understood std::remove() algorithm. I
got that understanding from here:

http://www.cppreference.com/cppalgorithm/remove.html

which simply says, "The remove() algorithm removes all of the elements
...."

fortunately comp.lang.c++ told me that is not true and Stroustrup on my
Desk also confirmed that. Sadly, Nicolai's book is not availale in my
country, So i looked for some correct online reference and I found this
one is frequently recommended:

Whats wrong there?
http://www.cplusplus.com/reference/algorithm/remove.html gives the same
explanation.
 
Z

Zeppe

arnuld said:
Hi all,

you folks have seen how wrongly I understood std::remove() algorithm. I
got that understanding from here:

http://www.cppreference.com/cppalgorithm/remove.html

which simply says, "The remove() algorithm removes all of the elements
...."

fortunately comp.lang.c++ told me that is not true and Stroustrup on my
Desk also confirmed that.

The standard "simply" sais the same:

"Eliminates all the elements referred to by iterator i in the range
[first, last) for which the following [...] conditions hold: *i == value
[...]."

So, I wouldn't blame that resource that much.

Regards,

Zeppe
 
G

Guest

Hi all,

you folks have seen how wrongly I understood std::remove() algorithm. I
got that understanding from here:

http://www.cppreference.com/cppalgorithm/remove.html

which simply says, "The remove() algorithm removes all of the elements
...."

It is not exactly wrong, but you need to read the next sentence too:
"The return value of this function is an iterator to the last element of
the new sequence that should contain no elements equal to val."
fortunately comp.lang.c++ told me that is not true and Stroustrup on my
Desk also confirmed that. Sadly, Nicolai's book is not availale in my
country, So i looked for some correct online reference and I found this
one is frequently recommended:

http://www.dinkumware.com/cpp.aspx

I would assume that all information on dinkumware's site is quite
accurate, it is after all the reference documentation to their library
implementation (keep an eye out for anything that might be
implementation specific though). The question is whether you understand
their descriptions better than the ones at www.cppreference.com. Another
quite useful site is www.cplusplus.com, they often have more details and
examples.
 
M

Michael DOUBEZ

arnuld a écrit :
Hi all,

you folks have seen how wrongly I understood std::remove() algorithm. I
got that understanding from here:

http://www.cppreference.com/cppalgorithm/remove.html

which simply says, "The remove() algorithm removes all of the elements
...."

fortunately comp.lang.c++ told me that is not true

I truth only one personn told you that.
and Stroustrup on my
Desk also confirmed that.

I don't have it here but I will check. I would be a surprise: saying
that std::remove doesn't remove would mean it is a misnommer. Perhaps
the distinction is a bit subtle and another world should have been used
but it doesn't mean it is false.
Sadly, Nicolai's book is not availale in my
country, So i looked for some correct online reference and I found this
one is frequently recommended:

http://www.dinkumware.com/cpp.aspx

but somone here also recommended the http://www.cppreference.com/ which
has quite wrong information. So I want to know, How is Dinkumware
Documentation ?

It is your understanding of 'remove' that is at fault. See defintion of
remove at SGI STL.
http://www.sgi.com/tech/stl/remove.html

Michael
 
A

arnuld

I don't have it here but I will check. I would be a surprise: saying
that std::remove doesn't remove would mean it is a misnommer. Perhaps
the distinction is a bit subtle and another world should have been used
but it doesn't mean it is false.
It is your understanding of 'remove' that is at fault. See defintion of
remove at SGI STL.
http://www.sgi.com/tech/stl/remove.html

yes, that is much better explanation :) I checked the NOTES:

NOTES >>> The meaning of "removal" is somewhat subtle. Remove does
NOTES >>> not destroy any iterators, and does not change the distance
NOTES >>> between first and last. (There's no way that it could do
NOTES >>> anything of thesort.) So, for example, if V is a vector,
NOTES >>> remove(V.begin(), V.end(), 0)does not change V.size(): V will
NOTES >>> contain just as many elements as it did before. Remove returns
NOTES >>> an iterator that points to the end of the resulting range after
NOTES >>> elements have been removed from it; it follows that the
NOTES >>> elements after that iterator are of no interest, and may be
NOTES >>> discarded.

e.g.

copy(V.begin(), V.end(), ostream_iterator<int>(cout, " "));
// The output is "3 1 4 1 5 9".

vector<int>::iterator new_end = remove(V.begin(), V.end(), 1);

copy(V.begin(), new_end, ostream_iterator<int>(cout, " "));
// The output is "3 4 5 9".


Therefore I understand that V.size() is still same but we have this range
of V.begin() & V.end() has got new iterator at say V.end_last() that says:

In iterator range ( V.begin(), V.end_last() ) contains elements of V
where integer 1 is not present (removed)

integer 1 is present In iterator range ( V.end_last(), V.end() )

Am I right ?

I think NO, I am wrong because this example says something else:

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>


int main()
{

std::vector<int> V;
V.push_back(3);
V.push_back(1);
V.push_back(4);
V.push_back(1);
V.push_back(5);
V.push_back(9);

std::copy(V.begin(), V.end(), std::eek:stream_iterator<int>(std::cout, " "));
// The output is "3 1 4 1 5 9".

std::vector<int>::iterator new_end = remove(V.begin(), V.end(), 1);

std::cout << "\n--------------- NEW RANGE -----------\n";
std::copy(V.begin(), new_end, std::eek:stream_iterator<int>(std::cout, " "));
// The output is "3 4 5 9".

std::cout << "\n-------------- REMOVED RANGE -------------\n";
std::copy( new_end, V.end(), std::eek:stream_iterator<int>( std::cout, " " ) );
std::cout << std::endl;


return 0;
}

============ OUTPUT ===================
~/programming/c++ $ g++ -ansi -pedantic -Wall -Wextra test.cpp
~/programming/c++ $ .a/
..a/: command not found
~/programming/c++ $ ./a.out
3 1 4 1 5 9
--------------- NEW RANGE -----------
3 4 5 9
-------------- REMOVED RANGE -------------
5 9
~/programming/c++ $


so did it really erase the iterator-range ( new_end, V.end() ) ?


NOTES >>> If you are removing elements from a Sequence, you may simply
NOTES >>> erase them. That is, a reasonable way of removingelements from
NOTES >>> a Sequence is S.erase(remove(S.begin(), S.end(), x), S.end())

I guess that is better and little Googling tells me that it is Scott
Meyer's technique # 32 :)




-- arnuld
http://lispmachine.wordpress.com
 
A

anon

arnuld said:
yes, that is much better explanation :) I checked the NOTES:

NOTES >>> The meaning of "removal" is somewhat subtle. Remove does
NOTES >>> not destroy any iterators, and does not change the distance
NOTES >>> between first and last. (There's no way that it could do
NOTES >>> anything of thesort.) So, for example, if V is a vector,
NOTES >>> remove(V.begin(), V.end(), 0)does not change V.size(): V will
NOTES >>> contain just as many elements as it did before. Remove returns
NOTES >>> an iterator that points to the end of the resulting range after
NOTES >>> elements have been removed from it; it follows that the
NOTES >>> elements after that iterator are of no interest, and may be
NOTES >>> discarded.

This link:
http://www.cplusplus.com/reference/algorithm/remove.html
tells this:
"Notice that this function does not alter the elements past the new end,
which keep their old values and are still accessible."
IOW elements after new_end contain garbage. This is also said in the
last sentence in your notes.
 
A

arnuld

This link:
http://www.cplusplus.com/reference/algorithm/remove.html
tells this:
"Notice that this function does not alter the elements past the new end,
which keep their old values and are still accessible."
IOW elements after new_end contain garbage. This is also said in the
last sentence in your notes.

yes, what i want to now is that where are the 2 removed integers ? They
are not erased, it is sure. look again at the RUN of the program:


~/programming/c++ $ ./a.out
3 1 4 1 5 9
--------------- NEW RANGE -----------
3 4 5 9
-------------- REMOVED RANGE -------------
5 9


so it looks like "3 4 5 9 5 9" and after 9 we have V.end() . Hence I
deduce that:

1.) the 2 integers, the 1s (ones) are pushed beyond V.end()

2.) 4 was pushed closer to 3 and 5 & 9 were copied (leaving the original
values at their original place intact)


3.) If they were pushed byond V.end(), then it really means they are
present at V.end() + 1 and V.end + 2 . (but those may contain garbage now)



-- arnuld
http://lispmachine.wordpress.com
 
A

anon

arnuld said:
yes, what i want to now is that where are the 2 removed integers ? They
are not erased, it is sure. look again at the RUN of the program:


~/programming/c++ $ ./a.out
3 1 4 1 5 9
--------------- NEW RANGE -----------
3 4 5 9
-------------- REMOVED RANGE -------------
5 9


so it looks like "3 4 5 9 5 9" and after 9 we have V.end() . Hence I
deduce that:

1.) the 2 integers, the 1s (ones) are pushed beyond V.end()

They are not pushed anywhere - they are removed. Beyond V.end() is some
random memory which you should not access
2.) 4 was pushed closer to 3 and 5 & 9 were copied (leaving the original
values at their original place intact)

4-5-9 were copied closer to 3, and in the range [new_end,end()) is left
garbage
3.) If they were pushed byond V.end(), then it really means they are
present at V.end() + 1 and V.end + 2 . (but those may contain garbage now)

When you access V.end(), or V.end()+n, you are accessing some random memory.
 
M

Michael DOUBEZ

arnuld a écrit :
yes, what i want to now is that where are the 2 removed integers ? They
are not erased, it is sure. look again at the RUN of the program:

Just to make clear what std::remove does (or could do - higly unlikely,
should find first element to remove first):

template<typename ForwardIterator, typename T>
iterator remove(ForwardIterator begin, ForwardIterator end, T value)
{
//find at least one element to remove
ForwardIterator new_end=begin;
for(;begin!=end;++begin)
{
if( ! (value == *begin) )
{
*new_end=*begin;
++new_end;
}
}
return new_end;
}


Michael
 
A

Anand Hariharan

(...)
NOTES >>> If you are removing elements from a Sequence, you may simply
NOTES >>> erase them. That is, a reasonable way of removingelements from
NOTES >>> a Sequence is S.erase(remove(S.begin(), S.end(), x), S.end())

I guess that is better and little Googling tells me that it is Scott
Meyer's technique # 32 :)

This article by Scott Meyers might help in explaining why remove
behaves like the way it does:

http://www.artima.com/cppsource/top_cpp_aha_moments.html

- Anand
 
A

arnuld

Just to make clear what std::remove does (or could do - higly unlikely,
should find first element to remove first):

I do not understadn template source-code yet but I will try :)
template<typename ForwardIterator, typename T>
iterator remove(ForwardIterator begin, ForwardIterator end, T value)
{
//find at least one element to remove
ForwardIterator new_end=begin;
for(;begin!=end;++begin)
{
if( ! (value == *begin) )
{
*new_end=*begin;
++new_end;
}
}
return new_end;
}


to me, it looks like it is creating a new iterator without affecting
the old iterators and the new iterator is of the same type as the older
begin iterator. We are just creating the new begin iterator and using it
to overwrite the elements, it is just that new iterator skips some value
(the value we do not want).


If I am wrong, Poke me in the eye.


-- arnuld
http://lispmachine.wordpress.com
 
M

Michael DOUBEZ

arnuld a écrit :
I do not understadn template source-code yet but I will try :)

Removing templating and using generic iterator on container storing
integers:

iterator remove(iterator begin, iterator end, int value)
{
iterator new_end=begin;
for(;begin!=end;++begin)
{
if( ! (value == *begin) )
{
*new_end=*begin;
++new_end;
}
}
return new_end;
}
[snip] We are just creating the new begin iterator and using it
to overwrite the elements, it is just that new iterator skips some value
(the value we do not want).

If I am wrong, Poke me in the eye.

That's it. Your binocular vision is safe.

Michael
 
J

James Kanze


And their explination is wrong as well. (At least they give
some examples, so you might be able to figure it out.)

std::remove doesn't remove anything. It can't; to "remove"
something, you need a container, and the algorithm doesn't have
access to one.

The description at Dinkumware is far more precise; the one at
SGI is pretty good as well. (The one at SGI may be the source
of the misinformation in the other two. It starts "Remove
removes from the range [first, last) all elements that are equal
to value." It immediately follows up with an explination of
what they mean by this, however, and if you read the entire
paragraph, it's quite clear. Apparently, the two references
mentioned above are guilty of quoting out of context.)
 
J

James Kanze

arnuld a écrit :
I truth only one personn told you that.
I don't have it here but I will check. I would be a surprise: saying
that std::remove doesn't remove would mean it is a misnommer. Perhaps
the distinction is a bit subtle and another world should have been used
but it doesn't mean it is false.

The English word "remove" is incorrect with regards to what
std::remove does. If you insist on using it, as the SGI
specification does, it is essential to describe exactly what you
mean by it, since the "normal" English meaning will result in a
misunderstanding.
 
M

Michael DOUBEZ

James Kanze a écrit :
The English word "remove" is incorrect with regards to what
std::remove does. If you insist on using it, as the SGI
specification does, it is essential to describe exactly what you
mean by it, since the "normal" English meaning will result in a
misunderstanding.

Well, you know best. English is not my native tongue.

Googling for the definiton of remove:

Remove 1
Definition: To move away from the position occupied; to cause to change
place; to displace; as, to remove a building.

Remove 2
Definition: To cause to leave a person or thing; to cause to cease to
be; to take away; hence, to banish; to destroy; to put an end to; to
kill; as, to remove a disease.

Remove 3
Definition: To dismiss or discharge from office; as, the President
removed many postmasters.

Remove 4
Definition: To change place in any manner, or to make a change in place;
to move or go from one residence, position, or place to another.

Remove 5
Definition: The act of removing; a removal.

....

Since the parameter of the std::remove() algorithm is a range and
considering the above definition, IMHO 'remove' is not that bad.
Perhaps 'strip' would have been more meaningful.

Removing from a container is more related to 'erase' (google again)
because it relate to the storage system:

erase: 1. To obliterate information from a storage medium, such as to
clear or to overwrite. 2. In a magnetic storage medium, to remove all
stored data by (a) changing the medium to an unmagnetized state or (b)
changing the medium to a predetermined magnetized state. 3. In paper
tape and punched card storage, to punch a hole at every punch position.

Hence the member function Container::erase() I guess.

Michael
 
J

Joe Greer

Well, you know best. English is not my native tongue.

Googling for the definiton of remove:

Remove 1
Definition: To move away from the position occupied; to cause to
change place; to displace; as, to remove a building.

Remove 2
Definition: To cause to leave a person or thing; to cause to cease to
be; to take away; hence, to banish; to destroy; to put an end to; to
kill; as, to remove a disease.

Remove 3
Definition: To dismiss or discharge from office; as, the President
removed many postmasters.

Remove 4
Definition: To change place in any manner, or to make a change in
place; to move or go from one residence, position, or place to
another.

Remove 5
Definition: The act of removing; a removal.

These are all pretty good. (Except for definition #2 which has the odd mix of 'take
away', 'banish', and 'destroy'. Destroy != banish in my mind.) The implication is
that the removed item is no longer there, not that it has been moved next door.
However, except for in a few cases (such as a building), remove doesn't necessisarily
imply that the item was destroyed either. So, I personally would say that remove is
generally an odd word to try to apply to a programming language action. Of course,
there are other standard method names I find odd as well. empty() is my favorite.
There is no way I would have guessed that this returned a boolean and did nothing
except for reading the docs. :)

joe
 
J

James Kanze

James Kanze a écrit :
Well, you know best. English is not my native tongue.

I'm not sure it's mine any more either---I haven't used it on a
regular basis for close to 40 years. (I'm not sure I have a
native tongue. I feel most at home in French, but any Frenchman
will spot my accent a mile off.)
Googling for the definiton of remove:

[...]

There are a number of very good on line dictionaries as well;
you don't even have to Google (and you know exactly how reliable
the source is). There are uses of remove whose meanings could
be more or less understood to apply. They're simply not the
ones we "expect" in this context.

The proof, of course, is the number of people who are confused
by it, and expect it to remove something from somewhere.
Since the parameter of the std::remove() algorithm is a range and
considering the above definition, IMHO 'remove' is not that bad.
Perhaps 'strip' would have been more meaningful.

I think that part of the problem is that "remove" is expected to
act on the sequence itself. Within the C++ community, at least,
I don't think that most people think in (or expect) functional
programming idioms. What the function really does (sort of) is
create a new sequence which contains all of the elements in the
original sequence, in order, except those it "removed". Except,
of course, that the "new sequence" isn't really new.

I suspect that Lisp programmers would feel right at home with
the name; from what little I've seen, they're quite used to the
functional programming idiom, and sharing parts of a list (a
sequence).

And while I don't like the name, I can't really think of a
better one, either. But the easiest way to explain it to a
beginner is to start by saying something along the lines of
"remove doesn't really remove", which really suggests very
strongly that the name isn't the right one.
Removing from a container is more related to 'erase' (google
again) because it relate to the storage system:

Except that "erase" isn't that often used in computer circles
for that operation. In my first container class (very, very
pre-standard), I used "delete", which I found perfect. The
compiler didn't however, and I was forced to change it---to
remove. (To me, erase suggests erasing something from a
blackboard, or pencil marks from a piece of paper. The
information is lost, but the support is still there. Something
like filling an array of int with 0's.)
erase: 1. To obliterate information from a storage medium, such as to
clear or to overwrite. 2. In a magnetic storage medium, to remove all
stored data by (a) changing the medium to an unmagnetized state or (b)
changing the medium to a predetermined magnetized state. 3. In paper
tape and punched card storage, to punch a hole at every punch position.
Hence the member function Container::erase() I guess.
From the above definition, I think that the names are reversed;
erase clears or overwrites (without removing the elements).

Perhaps part of the problem with remove, here, is that generally
within the STL, one thinks in terms of elements, and not values.
Remove "defines" a new sequence with the relevant values
removed, but does not remove elements.
 
A

arnuld

erase clears or overwrites (without removing the elements).

Ohh... One more confusion. Erase does not erase :-\

Perhaps part of the problem with remove, here, is that generally
within the STL, one thinks in terms of elements, and not values.
Remove "defines" a new sequence with the relevant values
removed, but does not remove elements.

I think a better name for std::remove will be:

std::remove_that_does_not_remove_BUT_actaully_is_just_an_iterator_creator

that explains well about what it does ;-)


-- arnuld
http://lispmachine.wordpress.com
 
A

arnuld

Perhaps part of the problem with remove, here, is that generally
within the STL, one thinks in terms of elements, and not values.
Remove "defines" a new sequence with the relevant values
removed, but does not remove elements.

perhaps this wil fit much betetr as a std::remove replacement:

std::remove_that_does_not_remove_BUT_actaully_is_just_an_iterator_creator_and_this_is_not_about_elements_but_values_only

that explains well about what it does ;-)
 

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,969
Messages
2,570,161
Members
46,708
Latest member
SherleneF1

Latest Threads

Top