forward_list::before_begin()
to forward_list::end()
Section: 23.3.7.3 [forward.list.iter] Status: C++11 Submitter: Joe Gottman Opened: 2011-03-13 Last modified: 2023-02-07
Priority: Not Prioritized
View all issues with C++11 status.
Discussion:
For an object c
of type forward_list<X, Alloc>
, the iterators
c.before_begin()
and c.end()
are part of the same underlying sequence,
so the expression c.before_begin() == c.end()
must be well-defined.
But the standard says nothing about what the result of this expression
should be. The forward iterator requirements says no dereferenceable
iterator is equal to a non-dereferenceable iterator and that two
dereferenceable iterators are equal if and only if they point to the
same element. But since before_begin()
and end()
are both
non-dereferenceable, neither of these rules applies.
Many forward_list
methods, such as insert_after()
, have a
precondition that the iterator passed to them must not be equal to
end()
. Thus, user code might look like the following:
void foo(forward_list<int>& c, forward_list<int>::iterator it) { assert(it != c.end()); c.insert_after(it, 42); }
Conversely, before_begin()
was specifically designed to be used with
methods like insert_after()
, so if c.before_begin()
is passed to
this function the assertion must not fail.
[2011-03-14: Daniel comments and updates the suggested wording]
The suggested wording changes are necessary but not sufficient. Since there
does not exist an equivalent semantic definition of cbefore_begin()
as
we have for cbegin()
, this still leaves the question open whether
the normative remark applies to cbefore_begin()
as well. A simple fix
is to define the operational semantics of cbefore_begin()
in terms of
before_begin()
.
[2011-03-24 Madrid meeting]
General agreement that this is a serious bug.
Pablo: Any objections to moving 2042 to Immediate? No objections.Proposed resolution:
Add to the definition of forward_list::before_begin()
[forwardlist.iter]
the following:
iterator before_begin(); const_iterator before_begin() const; const_iterator cbefore_begin() const;-1- Returns: A non-dereferenceable iterator that, when incremented, is equal to the iterator returned by
-?- Effects:begin()
.cbefore_begin()
is equivalent toconst_cast<forward_list const&>(*this).before_begin()
. -?- Remarks:before_begin() == end()
shall equal false.