Topic: Minor modification: nothrow guarantee for clear() in sequence container


Author: James Kanze <james.kanze@gmail.com>
Date: Mon, 30 Jul 2007 11:09:57 CST
Raw View
On Jul 23, 4:28 pm, Michael DOUBEZ <michael.dou...@free.fr> wrote:

> * Section 23.1.1/4, 23.1.2/7, 21.3.4/13

> The clear() member function in sequence container is said to be
> equivalent to:

> "erase(begin(), end())"

> Or erase() is nothrow only if the copy and assignment operator do not
> throw an exception. The standard is not explicit whether or not clear()
> is also nothrow except in the case of list modifier in 23.2.3.3/4

> "4. Throws: Nothing."

> *Proposed Resolution:

> Replace "erase(begin(), end())" by "Erases all elements in the
> container" in the mentionned occurences.

That's considerably less precise.  The current wording
guarantees that clear() has all of the same semantics as erase
(e.g. with regards to iterator validity, etc.)

> * Rationale:

> In the case of erase(begin(), end()) no copy or assignment operation is
> likely to take place. Thus clear() is not expected to throw.

A better solution would probably be to specify explicitly in
erase that if the first iterator is begin(), and the second
end(), neither the copy constructor nor the assignment operator
will be called.  I don't normally like such special cases, but
in this case, I suspect that there is some justification for it.

--
James Kanze (GABI Software)             email:james.kanze@gmail.com
Conseils en informatique orient   e objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place S   mard, 78210 St.-Cyr-l'   cole, France, +33 (0)1 30 23 00 34


---
[ 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.comeaucomputing.com/csc/faq.html                      ]





Author: howard.hinnant@gmail.com (Howard Hinnant)
Date: Tue, 31 Jul 2007 04:02:43 GMT
Raw View
In article <1185781837.435107.100540@q75g2000hsh.googlegroups.com>,
 James Kanze <james.kanze@gmail.com> wrote:

> On Jul 23, 4:28 pm, Michael DOUBEZ <michael.dou...@free.fr> wrote:
>
> > * Section 23.1.1/4, 23.1.2/7, 21.3.4/13
>
> > The clear() member function in sequence container is said to be
> > equivalent to:
>
> > "erase(begin(), end())"
>
> > Or erase() is nothrow only if the copy and assignment operator do not
> > throw an exception. The standard is not explicit whether or not clear()
> > is also nothrow except in the case of list modifier in 23.2.3.3/4
>
> > "4. Throws: Nothing."
>
> > *Proposed Resolution:
>
> > Replace "erase(begin(), end())" by "Erases all elements in the
> > container" in the mentionned occurences.
>
> That's considerably less precise.  The current wording
> guarantees that clear() has all of the same semantics as erase
> (e.g. with regards to iterator validity, etc.)
>
> > * Rationale:
>
> > In the case of erase(begin(), end()) no copy or assignment operation is
> > likely to take place. Thus clear() is not expected to throw.
>
> A better solution would probably be to specify explicitly in
> erase that if the first iterator is begin(), and the second
> end(), neither the copy constructor nor the assignment operator
> will be called.  I don't normally like such special cases, but
> in this case, I suspect that there is some justification for it.

What we really need, imho, is a compile-time guarantee that if clear()
is called, the value_type is not required to be MoveAssignable nor
MoveConstructible.  For example, if you construct a vector<const int>,
can you clear() it?

This would (in effect) require that clear() not be implementable as
erase(begin(), end()), as the latter transfers the guarantee to runtime.

If we choose to, we can allow vector<T> in C++0X to function with far
less fewer compile-time requirements on T than we did in C++03 (and
similarly for other containers).  This is not a decision that has been
made.  Nor is it an uncontroversial decision.  It is a decision yet to
be made.

Here is a visualization tool which attempts to describe the minimal
requirements on the value_type for the various members of vector (as an
example container) for the various member functions of vector.
Javascript enabled browser required.

http://home.twcny.rr.com/hinnant/cpp_extensions/vector_req.html

Click the checkboxes to prescribe what your value_type is capable of.
The vector synopsis indicates available functionality in black and
unavailable functionality in grey.  For example value_types (int, const
int, etc.), click a radio button which will update the check-box
requirements area and reflect the available vector interface.

In this simulation, the only thing vector<T,A>::clear requires is that T
is destructible.

-Howard

---
[ 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.comeaucomputing.com/csc/faq.html                      ]





Author: jcoffin@taeus.com (Jerry Coffin)
Date: Tue, 31 Jul 2007 05:22:09 GMT
Raw View
In article <1185781837.435107.100540@q75g2000hsh.googlegroups.com>,
james.kanze@gmail.com says...

[ ... ]

> A better solution would probably be to specify explicitly in
> erase that if the first iterator is begin(), and the second
> end(), neither the copy constructor nor the assignment operator
> will be called.  I don't normally like such special cases, but
> in this case, I suspect that there is some justification for it.

I think the specification could be made more general: that the copy
constructor/assignment operator is called no more than end()-last times
(where 'last' is the iterator specifying the end of the range to be
erased).

This does constrain the implementation. It prevents the data block from
being shrunk when/if you erase enough to drop the in-use section below a
specific threshold. Then again, while (I believe) that's currently
possible, it's certainly not required, so existing code shouldn't depend
on it anyway.

--
    Later,
    Jerry.

The universe is a figment of its own imagination.

---
[ 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.comeaucomputing.com/csc/faq.html                      ]





Author: James Kanze <james.kanze@gmail.com>
Date: Tue, 31 Jul 2007 11:54:30 CST
Raw View
On Jul 31, 7:22 am, jcof...@taeus.com (Jerry Coffin) wrote:
> In article <1185781837.435107.100...@q75g2000hsh.googlegroups.com>,
> james.ka...@gmail.com says...

> [ ... ]
> > A better solution would probably be to specify explicitly in
> > erase that if the first iterator is begin(), and the second
> > end(), neither the copy constructor nor the assignment operator
> > will be called.  I don't normally like such special cases, but
> > in this case, I suspect that there is some justification for it.

> I think the specification could be made more general: that the copy
> constructor/assignment operator is called no more than end()-last times
> (where 'last' is the iterator specifying the end of the range to be
> erased).

> This does constrain the implementation. It prevents the data block from
> being shrunk when/if you erase enough to drop the in-use section below a
> specific threshold. Then again, while (I believe) that's currently
> possible, it's certainly not required, so existing code shouldn't depend
> on it anyway.

An implementation is not currently allowed to shrink the block
anyway, since that might invalidate iterators.  Note that the
iterator guarantees are very strong:

    std::vector< int > v ;
    for ( int i = 0 ; i < 10 ; ++ i ) {
        v.push_back( i ) ;
    }
    assert( v.capacity() >= 10 ) ;
    v.clear() ;
    v.push_back( 0 ) ;
    v.push_back( 1 ) ;
    std::vector< int >::iterator i = v.begin() + 1 ;
    for ( int i = 2 ; i < 10 ; ++ i ) {
        v.push_back( i ) ;
    }
    //  here, iterator i is guaranteed to be valid,
    //  since we have not exceeded the previously
    //  known capacity.

--
James Kanze (GABI Software)             email:james.kanze@gmail.com
Conseils en informatique orient   e objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place S   mard, 78210 St.-Cyr-l'   cole, France, +33 (0)1 30 23 00 34



---
[ 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.comeaucomputing.com/csc/faq.html                      ]





Author: David Abrahams <dave@boost-consulting.com>
Date: Wed, 1 Aug 2007 08:49:26 CST
Raw View
on Tue Jul 31 2007, jcoffin-AT-taeus.com (Jerry Coffin) wrote:

> In article <1185781837.435107.100540@q75g2000hsh.googlegroups.com>,
> james.kanze@gmail.com says...
>
> [ ... ]
>
>> A better solution would probably be to specify explicitly in
>> erase that if the first iterator is begin(), and the second
>> end(), neither the copy constructor nor the assignment operator
>> will be called.  I don't normally like such special cases, but
>> in this case, I suspect that there is some justification for it.
>
> I think the specification could be made more general: that the copy
> constructor/assignment operator is called no more than end()-last
> times (where 'last' is the iterator specifying the end of the range
> to be erased).

That removes the possibility of throwing, but, by itself, does not
lift the requirement that T provide move assignment et al.  c.clear()
is fundamentally different from c.erase(c.begin(),c.end()) in the same
way that c.pop_back() is fundamentally different from
c.erase(prev(c.end()))

--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

The Astoria Seminar ==> http://www.astoriaseminar.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.comeaucomputing.com/csc/faq.html                      ]





Author: dave@boost-consulting.com (David Abrahams)
Date: Wed, 1 Aug 2007 14:36:59 GMT
Raw View
on Mon Jul 30 2007, James Kanze <james.kanze-AT-gmail.com> wrote:

> On Jul 23, 4:28 pm, Michael DOUBEZ <michael.dou...@free.fr> wrote:
>
>> * Section 23.1.1/4, 23.1.2/7, 21.3.4/13
>
>> The clear() member function in sequence container is said to be
>> equivalent to:
>
>> "erase(begin(), end())"
>
>> Or erase() is nothrow only if the copy and assignment operator do not
>> throw an exception. The standard is not explicit whether or not clear()
>> is also nothrow except in the case of list modifier in 23.2.3.3/4
>
>> "4. Throws: Nothing."
>
>> *Proposed Resolution:
>
>> Replace "erase(begin(), end())" by "Erases all elements in the
>> container" in the mentionned occurences.
>
> That's considerably less precise.  The current wording
> guarantees that clear() has all of the same semantics as erase
> (e.g. with regards to iterator validity, etc.)

Yes, but clear may be (in fact, probably is) overspecified.  It seems
every time we have specified semantics in terms of C++ code, we have
overspecified something.  In effect, less precision may be precisely
what we want.


--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

The Astoria Seminar ==> http://www.astoriaseminar.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.comeaucomputing.com/csc/faq.html                      ]





Author: James Kanze <james.kanze@gmail.com>
Date: Thu, 2 Aug 2007 09:41:28 CST
Raw View
On Aug 1, 4:36 pm, d...@boost-consulting.com (David Abrahams) wrote:
> on Mon Jul 30 2007, James Kanze <james.kanze-AT-gmail.com> wrote:
> > On Jul 23, 4:28 pm, Michael DOUBEZ <michael.dou...@free.fr> wrote:

> >> * Section 23.1.1/4, 23.1.2/7, 21.3.4/13

> >> The clear() member function in sequence container is said to be
> >> equivalent to:

> >> "erase(begin(), end())"

> >> Or erase() is nothrow only if the copy and assignment operator do not
> >> throw an exception. The standard is not explicit whether or not clear()
> >> is also nothrow except in the case of list modifier in 23.2.3.3/4

> >> "4. Throws: Nothing."

> >> *Proposed Resolution:

> >> Replace "erase(begin(), end())" by "Erases all elements in the
> >> container" in the mentionned occurences.

> > That's considerably less precise.  The current wording
> > guarantees that clear() has all of the same semantics as erase
> > (e.g. with regards to iterator validity, etc.)

> Yes, but clear may be (in fact, probably is) overspecified.  It seems
> every time we have specified semantics in terms of C++ code, we have
> overspecified something.  In effect, less precision may be precisely
> what we want.

Possibly.  In fact, in this case, I'd say certainly; IMHO, a
function named clear() should return the object to a "just
constructed" state.  (And it makes a lot of sense for erase(
begin(), end() ) to have different semantics than clear.)

It is, however, too late for that now.  Since 1998, clear() is
guaranteed to behave exactly like erase( begin(), end() ), and
the guarantees of erase (e.g. concerning iterator validity) are
also the guarantees of clear().  And while I'd still like some
function to return the object to its pristine state, if there's
any move to add such a function, it had better be called
reset(), or something else other than clear().

--
James Kanze (GABI Software)             email:james.kanze@gmail.com
Conseils en informatique orient   e objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place S   mard, 78210 St.-Cyr-l'   cole, France, +33 (0)1 30 23 00 34


---
[ 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.comeaucomputing.com/csc/faq.html                      ]





Author: David Abrahams <dave@boost-consulting.com>
Date: Thu, 2 Aug 2007 13:56:15 CST
Raw View
on Thu Aug 02 2007, James Kanze <james.kanze-AT-gmail.com> wrote:

> On Aug 1, 4:36 pm, d...@boost-consulting.com (David Abrahams) wrote:
>
>> Yes, but clear may be (in fact, probably is) overspecified.  It seems
>> every time we have specified semantics in terms of C++ code, we have
>> overspecified something.  In effect, less precision may be precisely
>> what we want.
>
> Possibly.  In fact, in this case, I'd say certainly; IMHO, a
> function named clear() should return the object to a "just
> constructed" state.  (And it makes a lot of sense for erase(
> begin(), end() ) to have different semantics than clear.)
>
> It is, however, too late for that now.  Since 1998, clear() is
> guaranteed to behave exactly like erase( begin(), end() ), and the
> guarantees of erase (e.g. concerning iterator validity) are also the
> guarantees of clear().

That all iterators are invalidated?  I'm pretty sure any semantics we
choose for clear() (including not invalidating iterators if that were
even possible) would be compatible with that.

> And while I'd still like some function to return the object to its
> pristine state, if there's any move to add such a function, it had
> better be called reset(), or something else other than clear().

I actually wouldn't want to require clear to do that.  *That* would be
a breaking change for std::vector, because it would lose its
capacity().

It would be pretty easy to make a backwards-compatible, nonthrowing
clear.  In fact, I'm willing to bet that every single implementation
of clear is already nonthrowing in practice.  We just need the
standardese to bless that.  Then I'd like to go one step further and
lift the move/copy ctor requirement.  None of these changes could
possibly have an effect on program semantics unless the standard
library implementation had perverted implementation of erase that
needlessly copied elements.

As an aside: some code *is* going to break when we move to C++0x.  All
breaking changes are a calculated risk.

--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

The Astoria Seminar ==> http://www.astoriaseminar.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.comeaucomputing.com/csc/faq.html                      ]





Author: James Kanze <james.kanze@gmail.com>
Date: Fri, 3 Aug 2007 09:40:48 CST
Raw View
David Abrahams wrote:
> on Thu Aug 02 2007, James Kanze <james.kanze-AT-gmail.com> wrote:

    [...]
> > And while I'd still like some function to return the object to its
> > pristine state, if there's any move to add such a function, it had
> > better be called reset(), or something else other than clear().

> I actually wouldn't want to require clear to do that.  *That* would be
> a breaking change for std::vector, because it would lose its
> capacity().

Exactly.  Whether it would have been better, originally, or
not, is really irrelevant today.

> It would be pretty easy to make a backwards-compatible, nonthrowing
> clear.  In fact, I'm willing to bet that every single implementation
> of clear is already nonthrowing in practice.  We just need the
> standardese to bless that.  Then I'd like to go one step further and
> lift the move/copy ctor requirement.  None of these changes could
> possibly have an effect on program semantics unless the standard
> library implementation had perverted implementation of erase that
> needlessly copied elements.

Agreed.  The only issue in my mind was that it might be
acceptable to specify this for the special case of
erase(begin(),end()) as well.

> As an aside: some code *is* going to break when we move to
> C++0x.  All breaking changes are a calculated risk.

Certainly.  But changes which break things have to be a lot more
motivated than changes that don't.  If there's an alternative
that doesn't break code, it is to be preferred.  And of course,
one can often make a reasonable guess as to the amount of code
that might be broken.  Adding a function reset() might also
break code (which e.g. uses #define reset somewhere before
including any headers), but it would seem to me far less risky
than changing the semantics of an existing function.

--
James Kanze (GABI Software)             email:james.kanze@gmail.com
Conseils en informatique orient   e objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place S   mard, 78210 St.-Cyr-l'   cole, France, +33 (0)1 30 23 00 34


---
[ 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.comeaucomputing.com/csc/faq.html                      ]





Author: jcoffin@taeus.com (Jerry Coffin)
Date: Sun, 5 Aug 2007 00:53:27 GMT
Raw View
In article <87zm1bo30u.fsf@grogan.peloton>, dave@boost-consulting.com
says...

[ ... ]

> > I think the specification could be made more general: that the copy
> > constructor/assignment operator is called no more than end()-last
> > times (where 'last' is the iterator specifying the end of the range
> > to be erased).
>
> That removes the possibility of throwing, but, by itself, does not
> lift the requirement that T provide move assignment et al.  c.clear()
> is fundamentally different from c.erase(c.begin(),c.end()) in the same
> way that c.pop_back() is fundamentally different from
> c.erase(prev(c.end()))

Maybe I'm missing something, but if a T can't be copied, moved, etc.,
how can it get into the container to start with?

--
    Later,
    Jerry.

The universe is a figment of its own imagination.

---
[ 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.comeaucomputing.com/csc/faq.html                      ]





Author: jcoffin@taeus.com (Jerry Coffin)
Date: Sun, 5 Aug 2007 00:57:44 GMT
Raw View
In article <1185873205.188372.27290@g4g2000hsf.googlegroups.com>,
james.kanze@gmail.com says...

[ ... ]

> An implementation is not currently allowed to shrink the block
> anyway, since that might invalidate iterators.

Good point -- so this change wouldn't add any new constraint.

--
    Later,
    Jerry.

The universe is a figment of its own imagination.

---
[ 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.comeaucomputing.com/csc/faq.html                      ]





Author: James Kanze <james.kanze@gmail.com>
Date: Sat, 4 Aug 2007 19:58:03 CST
Raw View
On Aug 4, 5:24 pm, AlbertoBarb...@libero.it (Alberto Ganesh Barbati)
wrote:
> David Abrahams ha scritto:

    [...]
> Now we have two goals:

> 1) expressing a no-throw guarantee for deque::clear() and vector::clear()

> 2) lift the move/copy requirements from deque::clear() and
> vector::clear() (as we will see below, there are no such requirement for
> list::clear(), right now)

> There are many ways to achieve that, of course. I'm pretty
> sure we can find a solution that doesn't break existing code.

That seems obvious, since the changes conform to LSP.  Even
today, an implementation in which clear() doesn't throw, and
doesn't actually require move/copy, is fully conformant---in
fact, I think that the first is true for all current
implementations, and I doubt that any current implementations
actually use move or copy in their implementations of clear().

> The first thing that comes to my mind is: erase() can throw only when
> calling copy constructors or assignment operators, so what if it doesn't
> call any? It could not throw then! But when does erase() actually need
> to call them? For a vector, that happens if and only if last != end().
> For a deque if and only if first != begin() and last != end(). The
> requirements for the invalidation of references implicitly mandate that.
>  So why not state the requirement explicitly? For example, for vector,
> we could change 23.2.5.2/5 from

> "Effects: Invalidates iterators and references at or after the point of
> the erase."

> to

> "Effects: Invalidates iterators and references at or after the point of
> the erase. If position == end() or last == end() no element is copied."

> Similarly for deque. This will quickly and easily get rid of goal number
> 1 as well as being a useful clarification on erase().

That's sort of what I had in mind (but I was no where near to
formulating it so precisely).

--
James Kanze (GABI Software)             email:james.kanze:gmail.com
Conseils en informatique orient   e objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place S   mard, 78210 St.-Cyr-l'   cole, France, +33 (0)1 30 23 00 34



---
[ 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.comeaucomputing.com/csc/faq.html                      ]





Author: dave@boost-consulting.com (David Abrahams)
Date: Sun, 5 Aug 2007 07:44:16 GMT
Raw View
on Sat Aug 04 2007, jcoffin-AT-taeus.com (Jerry Coffin) wrote:

> In article <87zm1bo30u.fsf@grogan.peloton>, dave@boost-consulting.com
> says...
>
> [ ... ]
>
>> > I think the specification could be made more general: that the copy
>> > constructor/assignment operator is called no more than end()-last
>> > times (where 'last' is the iterator specifying the end of the range
>> > to be erased).
>>
>> That removes the possibility of throwing, but, by itself, does not
>> lift the requirement that T provide move assignment et al.  c.clear()
>> is fundamentally different from c.erase(c.begin(),c.end()) in the same
>> way that c.pop_back() is fundamentally different from
>> c.erase(prev(c.end()))
>
> Maybe I'm missing something, but if a T can't be copied, moved, etc.,
> how can it get into the container to start with?

I believe there is a proposal on the table for passing an in-place
element construction function to a new container constructor and
assign member function.

--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

The Astoria Seminar ==> http://www.astoriaseminar.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.comeaucomputing.com/csc/faq.html                      ]





Author: Pete Becker <pete@versatilecoding.com>
Date: Sun, 5 Aug 2007 09:06:16 CST
Raw View
On 2007-08-05 03:44:16 -0400, dave@boost-consulting.com (David Abrahams) said:

>
> I believe there is a proposal on the table for passing an in-place
> element construction function to a new container constructor and
> assign member function.

Not just on the table: voted into the working draft at the Toronto
meeting two weeks ago. Instead of constructing an object and passing it
to insert() you pass the constructor arguments to emplace() which
handles the actual construction.

--
  Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)


---
[ 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.comeaucomputing.com/csc/faq.html                      ]





Author: David Abrahams <dave@boost-consulting.com>
Date: Sun, 5 Aug 2007 14:16:16 CST
Raw View
on Sun Aug 05 2007, Pete Becker <pete-AT-versatilecoding.com> wrote:

> On 2007-08-05 03:44:16 -0400, dave@boost-consulting.com (David Abrahams) said:
>
>>
>> I believe there is a proposal on the table for passing an in-place
>> element construction function to a new container constructor and
>> assign member function.
>
> Not just on the table: voted into the working draft at the Toronto
> meeting two weeks ago. Instead of constructing an object and passing
> it to insert() you pass the constructor arguments to emplace() which
> handles the actual construction.

Hmm.  It's more useful than what we have, but the (admittedly more
dangerous) interface using an in-place construction function would be
more flexible.

--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

The Astoria Seminar ==> http://www.astoriaseminar.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.comeaucomputing.com/csc/faq.html                      ]





Author: howard.hinnant@gmail.com (Howard Hinnant)
Date: Sun, 5 Aug 2007 21:13:53 GMT
Raw View
In article <MPG.211e8129960e77b5989974@news.sunsite.dk>,
 jcoffin@taeus.com (Jerry Coffin) wrote:

> In article <87zm1bo30u.fsf@grogan.peloton>, dave@boost-consulting.com
> says...
>
> [ ... ]
>
> > > I think the specification could be made more general: that the copy
> > > constructor/assignment operator is called no more than end()-last
> > > times (where 'last' is the iterator specifying the end of the range
> > > to be erased).
> >
> > That removes the possibility of throwing, but, by itself, does not
> > lift the requirement that T provide move assignment et al.  c.clear()
> > is fundamentally different from c.erase(c.begin(),c.end()) in the same
> > way that c.pop_back() is fundamentally different from
> > c.erase(prev(c.end()))
>
> Maybe I'm missing something, but if a T can't be copied, moved, etc.,
> how can it get into the container to start with?

In addition to the new emplace functionality already mentioned, one
might have a MoveConstructible object which isn't MoveAssignable.  One
might push_back a MoveConstructible object, and then clear(), and never
need MoveAssignable.  const int is one such object with these
characteristics.

-Howard

---
[ 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.comeaucomputing.com/csc/faq.html                      ]





Author: Michael DOUBEZ <michael.doubez@free.fr>
Date: Mon, 23 Jul 2007 08:28:00 CST
Raw View
Dear C++ committee,

* Section 23.1.1/4, 23.1.2/7, 21.3.4/13

The clear() member function in sequence container is said to be
equivalent to:

"erase(begin(), end())"

Or erase() is nothrow only if the copy and assignment operator do not
throw an exception. The standard is not explicit whether or not clear()
is also nothrow except in the case of list modifier in 23.2.3.3/4

"4. Throws: Nothing."

*Proposed Resolution:

Replace "erase(begin(), end())" by "Erases all elements in the
container" in the mentionned occurences.

* Rationale:

In the case of erase(begin(), end()) no copy or assignment operation is
likely to take place. Thus clear() is not expected to throw.


Sincerely,
Michael

---
[ 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.comeaucomputing.com/csc/faq.html                      ]