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

### 2182. `Container::[const_]reference` types are misleadingly specified

Section: 22.2.1 [container.requirements.general] Status: C++14 Submitter: Daniel Krügler Opened: 2012-08-20 Last modified: 2017-07-05

Priority: 0

View other active issues in [container.requirements.general].

View all other issues in [container.requirements.general].

View all issues with C++14 status.

Discussion:

According to Table 96 (Container requirements) the return type of `X::reference` and `X::const_reference` is "lvalue of `T`" and "`const` lvalue of `T`", respectively. This does not make much sense, because an lvalue is an expression category, not a type. It could also refer to an expression that has a type, but this doesn't make sense either in this context, because obviously `X::[const_]reference` are intended to refer to types.

Given the fact that `vector<bool>` has no real reference type for `X::[const_]reference` and this definition presumably is intended to cover such situations as well, one might think that the wording is just a sloppy form of "type that represents a [const] lvalue of `T`". But this is also problematic, because basically all proxy reference expressions are rvalues.

It is unclear what the intention is. A straightward way of fixing this wording could make `X::[const_]reference` identical to `[const] T&`. This holds for all Library containers except for `vector<bool>`.

Another way of solving this definition problem would be to impose a requirement that holds for both references and reference-like proxies. Both `X::reference` and `X::const_reference` would need to be convertible to `const T&`. Additionally `X::reference` would need to support for a mutable container an assignment expression of the form `declval<X::reference>() = declval<T>()` (this presentation intentionally does not require `declval<X::reference&>() = declval<T>()`).

Further, the Table 96 does not impose any relations between `X::reference` and `X::const_reference`. It seems that at least `X::reference` needs to be convertible to `X::const_reference`.

A related question is whether `X::reference` is supposed to be a mutable reference-like type, irrespective of whether the container is an immutable container or not. The way, type `match_results` defines `reference` identical to `const_reference` indicates one specific interpretation (similarly, the `initializer_list` template also defines member type `reference` equal to `const value_type&`). Note that this can be a different decision as that for `iterator` and `const_iterator`, e.g. for sets the type `X::reference` still is a mutable reference, even though `iterator` is described as constant iterator.

The proposed resolution is incomplete in regard to the last question.

[2013-03-15 Issues Teleconference]

Moved to Review.

Alisdair notes that this looks like wording in the right direction. Wonders about congruence of these typedefs and the similar ones for iterators.

[2013-09 Chicago]

Moved to Ready.

Consensus that the requirements should require real references, just like iterators, as containers are required to support at least ForwardIterators, which have the same restriction on references.

Matt will file a new issue for some additional concerns with regex `match_results`.

[2014-02-10, Daniel comments]

The new issue opened by Matt is LWG 2306.

[Issaquah 2014-02-11: Move to Immediate]

Issue should have been Ready in pre-meeting mailing.

Proposed resolution:

This wording is relative to N3376.

1. Change Table 96 — "Container requirements" as indicated:

   Table 96 — Container requirements
   Expression | Return type | Operational Semantics | Assertion/note pre-/post-condition | Complexity
   --- | --- | --- | --- | ---
   `X::reference` | lvalue of `T&` |  |  | compile time
   `X::const_reference` | const lvalue of `const` `T&` |  |  | compile time