CopyConstructible
Section: 23.2.7 [associative.reqmts], 23.2.8 [unord.req] Status: Open Submitter: Alisdair Meredith Opened: 2012-11-14 Last modified: 2015-10-22
Priority: 3
View other active issues in [associative.reqmts].
View all other issues in [associative.reqmts].
View all issues with Open status.
Discussion:
The requirements on the functors used to arrange elements in the various associative and unordered containers are given by a set of expressions in tables 102 — Associative container requirements, and 103 — Unordered associative container requirements. In keeping with Library convention these expressions make the minimal requirements necessary on their types. For example, we have the following 3 row extracts for the unordered containers:
Expression | Assertion/note pre-/post-condition |
|
Requires: hasher and key_equal are CopyConstructible .
|
|
Requires: hasher is CopyConstructible and
key_equal is DefaultConstructible .
|
|
Requires: hasher and key_equal are DefaultConstructible .
|
However, the signature for each class template requires that the functors must effectively be
CopyConstructible
for each of these expressions:
template <class Key, class T, class Hash = hash<Key>, class Pred = std::equal_to<Key>, class Allocator = std::allocator<std::pair<const Key, T> > > class unordered_map { ... // construct/destroy/copy explicit unordered_map(size_type n = see below, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); ... }
The letter of the standard can be honored as long as implementors recognize
their freedom to split this one signature into multiple overloads, so that
the documented default arguments (requiring a CopyConstructible
functor)
are not actually passed as default arguments.
As we look into the requirements for the copy constructor and copy-assignment operator, the requirements are even more vague, as the explicit requirements on the functors are not called out, other than saying that the functors are copied.
Must the functors be CopyAssignable
? Or is CopyConstructible
sufficient in this case? Do we require that the functors be Swappable
so that the copy-swap idiom can be deployed here? Note that a type that is both
CopyConstructible
and CopyAssignable
is still not guaranteed to
be Swappable
as the user may delete the swap
function for their
type in their own namespace, which would be found via ADL.
Some clean-up of the requirements table looks necessary, to at least document the
assignment behavior. In addition, we should have clear guidance on whether these
functors should always be CopyConstructible
, as suggested by the class
template definitions, or if the requirement tables are correct and we should
explicitly split up the constructors in the (unordered) associative containers
to no longer use default (function) arguments to obtain their defaulted functors.
I recommend the simplest solution would be to always require that the functors
for (unordered) associative containers be CopyConstructible
, above the
requirements tables themselves, so that the issue need not be addressed within
the tables. I suggest that the assignment operators for these containers add
the requirement that the functors be Swappable
, rather than forwarding
the corresponding Assignable
requirement.
[2013-03-15 Issues Teleconference]
Moved to Open.
Alisdair to propose wording.
[2014-06-08, Daniel comments]
The area of this issue partially overlaps what LWG 2227 addresses.
[2015-10-20, Daniel comments]
The revised resolution of LWG 2227 should resolve this issue as well. It follows the recommendations
of the submitter to require CopyConstructible
requirements for the function objects owned by containers,
but it does not impose any further fundamental requirements.
Proposed resolution:
See the resolution of LWG 2227.