allocator
, polymorphic_allocator
, and containers should forbid cv-qualified typesSection: 20.2.10 [default.allocator], 20.4.3.1 [mem.poly.allocator.class.general], 23.2 [container.requirements] Status: New Submitter: Stephan T. Lavavej Opened: 2023-04-02 Last modified: 2023-05-24
Priority: 3
View other active issues in [default.allocator].
View all other issues in [default.allocator].
View all issues with New status.
Discussion:
LWG 2447 adjusted what is now N4944 16.4.4.6.1 [allocator.requirements.general]/2.1 so that the Cpp17Allocator requirements are specified for cv-unqualified object types only.
However, nothing in 20.2.10 [default.allocator] restricts whatT
in allocator<T>
can be,
except where 20.2.10.2 [allocator.members]/2 and /6 require it to be complete for allocate()
and
allocate_at_least()
(and by implication, for deallocate()
). (Long ago, allocator
had member functions
whose signatures implied that const
-qualified types were forbidden, but those signatures were deprecated and
removed. This explains the phrasing of an MSVC static assertion.)
20.4.3.1 [mem.poly.allocator.class.general] says a bit more about Tp
in polymorphic_allocator<Tp>
but doesn't forbid anything. It says that if Tp
is a cv-unqualified object type, then
polymorphic_allocator<Tp>
meets the Cpp17Allocator requirements and allocator completeness requirements,
but that's all.
There's some implementation variation here. libstdc++ and MSVC reject allocator<const int>
. libc++
(as of LLVM 16) accepts it but this appears to have been an extension that they're trying to get rid of (their maintainers
may be able to comment further; see
llvm-project/commit/a54d028895c91da356a4aaf30e27a5a5b90dd313).
These 3 implementations all reject allocator<volatile int>
, polymorphic_allocator<const int>
,
and polymorphic_allocator<volatile int>
with varying messages.
The Standard should provide clarity here, by mandating that only cv-unqualified object types be given to allocator
,
polymorphic_allocator
, and containers. (allocator<void>
must also be allowed, of course. I forget
if polymorphic_allocator
is supposed to accept void
.) This would simply Standardize existing/desired practice.
While it may seem arcane, attempting to form vector<const T>
is a common novice mistake — so common that
MSVC had to add a static_assert
to emit a clear error message.
[2023-05-24; Reflector poll]
Set priority to 3 after reflector poll.
Proposed resolution: