This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++11 status.

### 2042. Comparing `forward_list::before_begin()` to `forward_list::end()`

Section: 99 [forwardlist.iter] Status: C++11 Submitter: Joe Gottman Opened: 2011-03-13 Last modified: 2016-01-28

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()` 99 [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 `begin()`.

> > -?- Effects: `cbefore_begin()` is equivalent to `const_cast<forward_list const&>(*this).before_begin()`.

> > -?- Remarks: `before_begin() == end()` shall equal false.