Section: 23.2.2 [container.requirements.general] Status: NAD Editorial Submitter: Martin Sebor Opened: 2006-06-14 Last modified: 2016-01-28
Priority: Not Prioritized
View other active issues in [container.requirements.general].
View all other issues in [container.requirements.general].
View all issues with NAD Editorial status.
Duplicate of: 479
Discussion:
C++ Standard Library templates that take an allocator as an argument
are required to call the allocate()
and
deallocate()
members of the allocator object to obtain
storage. However, they do not appear to be required to call any other
allocator members such as construct()
,
destroy()
, address()
, and
max_size()
. This makes these allocator members less than
useful in portable programs.
It's unclear to me whether the absence of the requirement to use these allocator members is an unintentional omission or a deliberate choice. However, since the functions exist in the standard allocator and since they are required to be provided by any user-defined allocator I believe the standard ought to be clarified to explictly specify whether programs should or should not be able to rely on standard containers calling the functions.
I propose that all containers be required to make use of these functions.
[ Batavia: We support this resolution. Martin to provide wording. ]
[ pre-Oxford: Martin provided wording. ]
[ 2009-04-28 Pablo adds: ]
N2554 (scoped allocators), N2768 (allocator concepts), and N2810 (allocator defects), address all of these points EXCEPT
max_size()
. So, I would add a note to that affect and re-class the defect as belonging to section 23.2.2 [container.requirements.general].
[ 2009-07 Frankfurt ]
The comment in the description of this issue that this "would be" rendered editorial by the adoption of N2257 is confusing. It appears that N2257 was never adopted.
[ 2009-10 Santa Cruz: ]
NAD Editorial. Addressed by N2982.
Proposed resolution:
Specifically, I propose to change 23.2 [container.requirements], p9 as follows:
-9- Copy constructors for all container types defined in this clause that are parametrized on
Allocator
copyanthe allocator argument from their respective first parameters. All other constructors for these container types take anconstAllocator&
argument (20.1.6), an allocator whosevalue_type
is the same as the container'svalue_type
. A copy of this argumentisshall be used for any memory allocation and deallocation performed,by these constructors and by all member functions,during the lifetime of each container object. Allocation shall be performed "as if" by calling theallocate()
member function on a copy of the allocator object of the appropriate type New Footnote), and deallocation "as if" by callingdeallocate()
on a copy of the same allocator object of the corresponding type. A copy of this argument shall also be used to construct and destroy objects whose lifetime is managed by the container, including but not limited to those of the container'svalue_type
, and to obtain their address. All objects residing in storage allocated by a container's allocator shall be constructed "as if" by calling theconstruct()
member function on a copy of the allocator object of the appropriate type. The same objects shall be destroyed "as if" by callingdestroy()
on a copy of the same allocator object of the same type. The address of such objects shall be obtained "as if" by calling theaddress()
member function on a copy of the allocator object of the appropriate type. Finally, a copy of this argument shall be used by its container object to determine the maximum number of objects of the container'svalue_type
the container may store at the same time. The container member functionmax_size()
obtains this number from the value returned by a call toget_allocator().max_size()
. In all container types defined in this clause that are parametrized onAllocator
, the memberget_allocator()
returns a copy of theAllocator
object used to construct the container.258)New Footnote: This type may be different from
Allocator
: it may be derived fromAllocator
viaAllocator::rebind<U>::other
for the appropriate typeU
.
The proposed wording seems cumbersome but I couldn't think of a better
way to describe the requirement that containers use their
Allocator
to manage only objects (regardless of their
type) that persist over their lifetimes and not, for example,
temporaries created on the stack. That is, containers shouldn't be
required to call Allocator::construct(Allocator::allocate(1),
elem)
just to construct a temporary copy of an element, or
Allocator::destroy(Allocator::address(temp), 1)
to
destroy temporaries.
[ Howard: This same paragraph will need some work to accommodate 431. ]
[ post Oxford: This would be rendered NAD Editorial by acceptance of N2257. ]