Title
allocator, polymorphic_allocator, and containers should forbid cv-qualified types
Status
new
Section
[default.allocator][mem.poly.allocator.class.general] [container.requirements]
Submitter
Stephan T. Lavavej

Created on 2023-04-02.00:00:00 last changed 11 months ago

Messages

Date: 2023-05-15.00:00:00

[ 2023-05-24; Reflector poll ]

Set priority to 3 after reflector poll.

Date: 2023-04-02.00:00:00

LWG 2447 adjusted what is now N4944 [allocator.requirements.general]/2.1 so that the Cpp17Allocator requirements are specified for cv-unqualified object types only.

However, nothing in [default.allocator] restricts what T in allocator<T> can be, except where [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.)

[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.

History
Date User Action Args
2023-05-24 14:33:00adminsetmessages: + msg13567
2023-04-02 00:00:00admincreate