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

### 180. Container member iterator arguments constness has unintended consequences

Section: 21.3.3 [basic.string] Status: CD1 Submitter: Dave Abrahams Opened: 1999-07-01 Last modified: 2016-11-12

Priority: Not Prioritized

View other active issues in [basic.string].

View all other issues in [basic.string].

View all issues with CD1 status.

Discussion:

It is the constness of the container which should control whether it can be modified through a member function such as erase(), not the constness of the iterators. The iterators only serve to give positioning information.

Here's a simple and typical example problem which is currently very difficult or impossible to solve without the change proposed below.

Wrap a standard container C in a class W which allows clients to find and read (but not modify) a subrange of (C.begin(), C.end()]. The only modification clients are allowed to make to elements in this subrange is to erase them from C through the use of a member function of W.

[ post Bellevue, Alisdair adds: ]

> This issue was implemented by N2350 for everything but `basic_string`.

> Note that the specific example in this issue (`basic_string`) is the one place we forgot to amend in N2350, so we might open this issue for that single container?

[ Sophia Antipolis: ]

> This was a fix that was intended for all standard library containers, and has been done for other containers, but string was missed.

> The wording updated.

> We did not make the change in `replace`, because this change would affect the implementation because the string may be written into. This is an issue that should be taken up by concepts.

> We note that the supplied wording addresses the initializer list provided in N2679.

Proposed resolution:

Update the following signature in the `basic_string` class template definition in 21.3.3 [basic.string], p5:

>     namespace std {
>       template<class charT, class traits = char_traits<charT>,
>         class Allocator = allocator<charT> >
>       class basic_string {

>         ...

>         iterator insert(const_iterator p, charT c);
>         void insert(const_iterator p, size_type n, charT c);
>         template<class InputIterator>
>           void insert(const_iterator p, InputIterator first, InputIterator last);
>         void insert(const_iterator p, initializer_list<charT>);

>         ...

>         iterator erase(const_iterator const_position);
>         iterator erase(const_iterator first, const_iterator last);

>         ...

>       };
>     }

Update the following signatures in 21.3.3.7.4 [string.insert]:

>     iterator insert(const_iterator p, charT c);
>     void insert(const_iterator p, size_type n, charT c);
>     template<class InputIterator>
>       void insert(const_iterator p, InputIterator first, InputIterator last);
>     void insert(const_iterator p, initializer_list<charT>);

Update the following signatures in 21.3.3.7.5 [string.erase]:

>     iterator erase(const_iterator const_position);
>     iterator erase(const_iterator first, const_iterator last);

Rationale:

The issue was discussed at length. It was generally agreed that 1) There is no major technical argument against the change (although there is a minor argument that some obscure programs may break), and 2) Such a change would not break const correctness. The concerns about making the change were 1) it is user detectable (although only in boundary cases), 2) it changes a large number of signatures, and 3) it seems more of a design issue that an out-and-out defect.

The LWG believes that this issue should be considered as part of a general review of const issues for the next revision of the standard. Also see issue 200.