1301. clear() and assignment

Section: 26.2.3 [sequence.reqmts] Status: NAD Editorial Submitter: Nicolai Josuttis Opened: 2010-01-01 Last modified: 2016-02-10

Priority: Not Prioritized

View other active issues in [sequence.reqmts].

View all other issues in [sequence.reqmts].

View all issues with NAD Editorial status.

Discussion:

I propose that clear() be defined to be equivalent to erase(begin(),end()) except not using copy or move of elements.

To: C++ libraries mailing list
Message c++std-lib-26465

and specifiying as post: size()==0 might also not be appropriate because forward-Lists provide no size(), this it should be: post: empty()==true

Bjarne Stroustrup schrieb/wrote:

To: C++ libraries mailing list
Message c++std-lib-26458

in table 94 we define clear() as:

a.clear() void erase(begin(), end())
post: size() == 0

Now erase requires assignment (MoveAssignable) which makes sense if we have to move an element, but why should that be required from clear() where all elements are destroyed?

[ 2010-01-23 Alisdiar provides wording. ]

[ 2010-01-30 Moved to Tentatively Ready after 5 positive votes on c++std-lib. ]

[ 2010-01-30 Daniel opens: ]

First, I read the newly proposed spec for clear() that it does in general not invalidate a previous past-the-end iterator value, but deque says in 26.3.8.4 [deque.modifiers] for the semantics of erase that erasures at the end will invalidate the past-the-end iterator. With removal of a direct binding between clear() and erase() there seem to be some fixes necessary. One way to fix that would be to mention in Table 94 that this "may also invalidate the past-the-end iterator" and then to mention for all specific containers where this does not happen, the exception, [1] e.g. in std::vector. std::vector has no own specification of clear() and one aspect of the closed issue 1102 was to realize just that (indirectly via erase). IMO we should now add an extra specification for clear(). Btw.: std::vector::erase reads to me that it would invalidate previous past-the-end values (and that seems correct in general).

Before I will provide explicit wording, I would like to discuss these points.

[1] std::list does fortunately specify that clear does not invalidate the past-the-end iterator.

[ 2010-02-08 Moved to Tentatively NAD Editorial after 5 positive votes on c++std-lib. Rationale added below. ]

Rationale:

Solved as proposed by LWG 704.

Proposed resolution:

Change 26.2.1 [container.requirements.general]/10:

Unless otherwise specified (see 23.2.4.1, 23.2.5.1, 23.3.2.3, and 23.3.6.4) all container types defined in this Clause meet the following additional requirements:

Replace the following words from Table 94 — Sequence container requirements (in addition to container) in 26.2.3 [sequence.reqmts]:

Table 94 — Sequence container requirements (in addition to container)
Expression Return type Assertion/note
pre-/post-condition
a.clear() void erase(begin(), end())
Destroys all elements in the container a. Invalidates all references, pointers, and iterators referring to the elements of a and may invalidate the past-the-end iterator.
post: size() == 0 a.empty() == true.

Add a new paragraph after 26.3.9.5 [forwardlist.modifiers]/23:

void clear();

23 Effects: Erases all elements in the range [begin(),end()).

Remarks: Does not invalidate past-the-end iterators.