Topic: Semantics of insert/erase
Author: "James Russell Kuyper Jr." <kuyper@wizard.net>
Date: Fri, 24 Aug 2001 16:33:13 GMT Raw View
Scott Meyers wrote:
>
> Are there any semantics for insert or erase in sequences beyond those in
> Table 67? In particular, consider this (motivated by a thread in clcm):
>
> vector<T> v;
> ...
> v.erase(v.begin());
>
> Does this call the destructor of v.begin()? I'd expect it would.
Yes. v.begin() is an iterator, a copy of which will be passed to
v.erase(), after which both the copy and the original will be destroyed.
However, I suspect that you're actually wondering about whether the
object pointed at by v.begin() will be destroyed, rather than the
iterator itself. :-)
> Responders to the thread in clcm have been unanimous in saying that it will
> not. Instead, they agree, *v.begin() will be the target of an assignment,
> and the only element destroyed will *(v.end()-1).
I concur.
> Table 67 says that the expression a.erase(q) "erases the element pointed to
> by q." Lovely: the member function erase is defined in terms of the word
> "erase," and as far as I can tell, that word is never defined. A similar
> situation exists for the member function insert and the word "insert".
>
> I'm hoping the Standard has more to say about this than exists in Table
> 67. Does it?
The contained objects are required to be both CopyConstructible and
Assignable, and I can't think of anything else the standard says which
would constrain an implementor to use one or the other of those
techniques. The code to implement erase() using copy assignment is
slightly simpler, and I suspect that the member functions it calls will
tend to be simpler as well, so I'd expect it to be the preferred
technique.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Matthew Austern <austern@research.att.com>
Date: Fri, 24 Aug 2001 17:34:58 GMT Raw View
Scott Meyers <smeyers@aristeia.com> writes:
> Are there any semantics for insert or erase in sequences beyond those in
> Table 67? In particular, consider this (motivated by a thread in clcm):
>
> vector<T> v;
> ...
> v.erase(v.begin());
>
> Does this call the destructor of v.begin()? I'd expect it would.
> Responders to the thread in clcm have been unanimous in saying that it will
> not. Instead, they agree, *v.begin() will be the target of an assignment,
> and the only element destroyed will *(v.end()-1).
As a general rule, I don't think you should have such specific
expectations about STL containers. The big thing to remember is that
STL containers are defined in terms of values, not in terms of object
identity.
What you can expect, when you call C.erase(i), is that afterwards the
sequence of values in C will be the same as it was before, but with *i
missing.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Scott Meyers <smeyers@aristeia.com>
Date: Fri, 24 Aug 2001 17:48:01 GMT Raw View
On Fri, 24 Aug 2001 16:33:13 GMT, James Russell Kuyper Jr. wrote:
> The contained objects are required to be both CopyConstructible and
> Assignable, and I can't think of anything else the standard says which
> would constrain an implementor to use one or the other of those
> techniques. The code to implement erase() using copy assignment is
> slightly simpler, and I suspect that the member functions it calls will
> tend to be simpler as well, so I'd expect it to be the preferred
> technique.
None of which has any bearing on the semantics of the word "erase" as used
in the Standard. The question is important: does the Standard say what it
means to "erase" something? I assumed that it meant to destroy it. Others
obviously assumed otherwise.
Consider:
T x, y;
x = y; // Does this "erase" x?
Scott
--
Check out "THE C++ Seminar," http://www.gotw.ca/cpp_seminar/
Also check out "Effective STL," http://www.aw.com/estl/
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: "Steven E. Harris" <seharris@raytheon.com>
Date: Fri, 24 Aug 2001 18:31:15 GMT Raw View
Scott Meyers <smeyers@aristeia.com> writes:
> None of which has any bearing on the semantics of the word "erase"
> as used in the Standard. The question is important: does the
> Standard say what it means to "erase" something? I assumed that it
> meant to destroy it. Others obviously assumed otherwise.
To "erase" in this context is to overwrite the target element's value
with some other value, or nothing. That is, to "erase" it is to change
its value be something else. If there's nothing else to replace the
value with, destroy the element. In either case, the original value is
gone.
Assignment and copy construction must not be semantically distinct for
the value_type. The container is allowed to create, destroy, and copy
the contained values as it sees fit. Therefore, the destructor must
not be a significant "hook" or "event" for the value type any more
than assignment. Assignment and destruction must run similar code, if
any, on the current value. boost::shared_ptr=B9, for example, runs
dispose() in both operator=3D() and its destructor. If these
distinctions are important for your value_type, then you shouldn't be
storing this type in container.
> Consider:
>=20
> T x, y;
> x =3D y; // Does this "erase" x?
Sort of. It erased variable x's value and replaced it with y's value.
Footnotes:=20
=B9 http://www.boost.org/boost/smart_ptr.hpp
--=20
Steven E. Harris :: seharris@raytheon.com
Raytheon :: http://www.raytheon.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Scott Meyers <smeyers@aristeia.com>
Date: Fri, 24 Aug 2001 19:44:13 GMT Raw View
On Fri, 24 Aug 2001 18:31:15 GMT, Steven E. Harris wrote:
> To "erase" in this context is to overwrite the target element's value
> with some other value, or nothing.
The Standard says this where?
BTW, I'm not saying I have any objection to the current behavior. I'm
just interested in where the Standard specifies the semantics. From what
I can tell, it doesn't.
Scott
--
Check out "THE C++ Seminar," http://www.gotw.ca/cpp_seminar/
Also check out "Effective STL," http://www.aw.com/estl/
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: "Serge Smeesters" <sergesmeesters@netcourrier.com>
Date: Sat, 25 Aug 2001 02:29:51 GMT Raw View
> Are there any semantics for insert or erase in sequences beyond those in
> Table 67? In particular, consider this (motivated by a thread in clcm):
>
> vector<T> v;
> ...
> v.erase(v.begin());
>
> Does this call the destructor of v.begin()? I'd expect it would.
> Responders to the thread in clcm have been unanimous in saying that it will
> not. Instead, they agree, *v.begin() will be the target of an assignment,
> and the only element destroyed will *(v.end()-1).
>
> Table 67 says that the expression a.erase(q) "erases the element pointed to
> by q." Lovely: the member function erase is defined in terms of the word
> "erase," and as far as I can tell, that word is never defined. A similar
> situation exists for the member function insert and the word "insert".
>
> I'm hoping the Standard has more to say about this than exists in Table
> 67. Does it?
Your question interest me fully.
I don't know what is this Table 67
(I'v not yet the C++ ANSI/ISO documentation
simply because I've no credit card) ..
So, I've just find semantique at
http://www.sgi.com/tech/stl/Sequence.html
An effectively, I dont find semantique ...
IMHO, I think that Sequence give a weak semantic to
'erase' and 'insert' giving manageability to models.
The 'std::vector' model explicite that
"memory management is automatic" and then don't folow
the semantics about creation or destuction coming from
conceptual "inherited" (from Sequence).
The elements concept don't mach wich instance conciderations.
IMHO, it's an important thing to understand about stl !
IMHO, Use facade or interface like classes or pointer
as stl containers elements concreteness should
be handle by an otherway.
--
Serge Smeesters
http://www.sesa.ucl.ac.be/serge/
Look at this video (to fun ;))) :
http://www.sesa.ucl.ac.be/serge/Video/dancemonkeyboy.mpg
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: "John Hickin" <hickin@nortelnetworks.com>
Date: Sat, 25 Aug 2001 02:31:44 GMT Raw View
Scott Meyers wrote:
>
> Are there any semantics for insert or erase in sequences beyond those in
> Table 67? In particular, consider this (motivated by a thread in clcm):
>
> vector<T> v;
> ...
> v.erase(v.begin());
>
> Does this call the destructor of v.begin()? I'd expect it would.
Interestingly enough, the notes accompanying SGI's STL state that erase
destroys the element; their implementation (stl_vector.h), however, uses
an overlapping copy, which is followed by the last element's
destruction.
> Responders to the thread in clcm have been unanimous in saying that it will
> not. Instead, they agree, *v.begin() will be the target of an assignment,
> and the only element destroyed will *(v.end()-1).
Of course, assuming the validity of the above algorithm, you have the
special case where there is but one element, which demands the
destruction of v.begin() and no assignment.
This is, perhaps, the point of your question: that the standard might
permit different types of bevahior for erasing the only element of a
vector as compared to erasing the first element of a multi element
vector. Same for pop_front. If v were a std::list<T>, one could expect
no other behavior than element destruction on erasure. Subtle behavioral
differences arise both at run time and compile time.
Good question.
I guess it all boils down to what is meant by assignable, which is a
requirement that the element type of every container must meet. Here the
standard is fairly wide open: it says merely that x=y must leave x
equivalent to y.
>
> Table 67 says that the expression a.erase(q) "erases the element pointed to
> by q." Lovely: the member function erase is defined in terms of the word
> "erase," and as far as I can tell, that word is never defined. A similar
> situation exists for the member function insert and the word "insert".
If one counts values, then the count of values equivalent to x must
decrease by one while those equivalent to y must increase by 1 after
x=y. Perhaps erasse(p) could be defined so that the value count of
elements equivalent to *P is decreased by 1.
Certainly in the interest of efficiency, the copy way of erasure is a
good idea. But with the above noted differences in behavior, it puts
added responsibility of the designer of the element type.
Regards, John.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: agriff@tin.it (Andrea Griffini)
Date: Sat, 25 Aug 2001 02:34:33 GMT Raw View
On Fri, 24 Aug 2001 09:53:05 GMT, Scott Meyers <smeyers@aristeia.com>
wrote:
>Are there any semantics for insert or erase in sequences beyond those in
>Table 67? In particular, consider this (motivated by a thread in clcm):
>
> vector<T> v;
> ...
> v.erase(v.begin());
>
>Does this call the destructor of v.begin()? I'd expect it would.
That would require to use the copy constructor + destructor
on all the elements of the vector. I think that an
implementation based on assigment is going to be on average
more efficient.
Sure the "guts" of all objects must be copied around, but
at least the common skeleton of the objects (if any) will
be safe. The problem with destroying the first element is
that there's no easy way to "shift" the others (I've heard
about a "copy destructor" proposal to be used for efficently
moving objects around, tho).
>I'm hoping the Standard has more to say about this than exists in Table
>67. Does it?
I've found this on my outdated docs:
[lib.vector.modifiers]
...
iterator erase(iterator position);
iterator erase(iterator first, iterator last);
Effects:
Invalidates all the iterators and references
after the point of the erase.
Complexity:
The destructor of T is called the number of
times equal to the number of the elements
erased, but the assignment operator of T is
called the number of times equal to the
number of elements in the vector after the
erased elements.
Throws:
Nothing unless an exception is thrown by the
copy constructor or assignment operator of T.
So the standard seems quite clear about that assigment
will be used to do the shifting and the destructor
will be called always on the last element.
HTH
Andrea
--
Andrea Griffini, Programmer
http://www.netservers.com/~agriff
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Scott Meyers <smeyers@aristeia.com>
Date: Sat, 25 Aug 2001 04:13:36 GMT Raw View
On Sat, 25 Aug 2001 02:34:33 GMT, Andrea Griffini wrote:
> I've found this on my outdated docs:
> The destructor of T is called the number of
> times equal to the number of the elements
> erased, but the assignment operator of T is
> called the number of times equal to the
> number of elements in the vector after the
> erased elements.
Ah, very good, that's 23.2.4.3, and it's not outdated. I don't know why I
didn't see it the first time I looked. Thanks very much. It seems pretty
clear that assignment followed by destruction of "excess" elements is
exactly what's supposed to happen. Thanks again for the reference.
Scott
--
Check out "THE C++ Seminar," http://www.gotw.ca/cpp_seminar/
Also check out "Effective STL," http://www.aw.com/estl/
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Scott Meyers <smeyers@aristeia.com>
Date: Fri, 24 Aug 2001 09:53:05 GMT Raw View
Are there any semantics for insert or erase in sequences beyond those in
Table 67? In particular, consider this (motivated by a thread in clcm):
vector<T> v;
...
v.erase(v.begin());
Does this call the destructor of v.begin()? I'd expect it would.
Responders to the thread in clcm have been unanimous in saying that it will
not. Instead, they agree, *v.begin() will be the target of an assignment,
and the only element destroyed will *(v.end()-1).
Table 67 says that the expression a.erase(q) "erases the element pointed to
by q." Lovely: the member function erase is defined in terms of the word
"erase," and as far as I can tell, that word is never defined. A similar
situation exists for the member function insert and the word "insert".
I'm hoping the Standard has more to say about this than exists in Table
67. Does it?
Thanks,
Scott
--
Check out "THE C++ Seminar," http://www.gotw.ca/cpp_seminar/
Also check out "Effective STL," http://www.aw.com/estl/
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]