Container::[const_]reference
types are misleadingly specifiedSection: 23.2.2 [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.
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.
Change Table 96 — "Container requirements" as indicated:
Expression | Return type | Operational Semantics |
Assertion/note pre-/post-condition |
Complexity |
---|---|---|---|---|
X::reference
|
T&
|
compile time | ||
X::const_reference
|
const T&
|
compile time |