This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.
flat_foo
allocator-extended constructors lack move semanticsSection: 23.6.8 [flat.map], 23.6.9 [flat.multimap], 23.6.11 [flat.set], 23.6.12 [flat.multiset] Status: New Submitter: Arthur O'Dwyer Opened: 2022-10-25 Last modified: 2023-06-16
Priority: 2
View other active issues in [flat.map].
View all other issues in [flat.map].
View all issues with New status.
Discussion:
Compare 23.6.4.2 [priqueue.cons]'s overload set
priority_queue(const Compare&, const Container&); priority_queue(const Compare&, Container&&); template<class Alloc> priority_queue(const Compare&, const Container&, const Alloc&); template<class Alloc> priority_queue(const Compare&, Container&&, const Alloc&);
against 23.6.8 [flat.map]'s overload set
flat_map(key_container_type, mapped_container_type); template<class Allocator> flat_map(const key_container_type&, const mapped_container_type&, const Allocator& a);
I see two issues here:
(A) The allocator-extended ctor of flat_map
always copies the key_container
and value_container
,
when it should be move-enabled.
(B) Almost certainly the Allocator
parameter should be named Alloc
instead, and there should be a
separate "Constructors with allocators" section with wording similar to 23.6.4.3 [priqueue.cons.alloc] explaining that
these ctors don't participate in overload resolution unless
uses_allocator_v<KeyContainer, Alloc> && uses_allocator_v<MappedContainer, Alloc>
.
I suggest this overload set to replace the two overloads above:
flat_map(key_container_type, mapped_container_type); template<class Alloc> flat_map(const key_container_type&, const mapped_container_type&, const Alloc& a); template<class Alloc> flat_map(const key_container_type&, mapped_container_type&&, const Alloc& a); template<class Alloc> flat_map(key_container_type&&, const mapped_container_type&, const Alloc& a); template<class Alloc> flat_map(key_container_type&&, mapped_container_type&&, const Alloc& a);
This preserves the apparent assumption that KeyContainer(std::move(kc))
is always efficient but
KeyContainer(std::move(kc), otheralloc)
might not be. Similar wording changes would have to be made to all the
flat_foo
containers.
template<class T, class Comp = std::less<T>, class Container = std::pmr::vector<T>> using pmr_flat_set = std::flat_set<T, Comp, Container>; std::pmr::vector<pmr_flat_set<int>> vs; std::pmr::vector<int> data = {1,2,3}; vs.reserve(1); vs.emplace_back(std::move(data)); // constructs-in-place with the argument list (std::move(data), get_allocator()) // BEFORE: copies (causes heap traffic) // AFTER: moves (no heap traffic)
[2022-11-04; Reflector poll]
Set priority to 2 after reflector poll.
[2023-06-14 Varna]
Mentioned in P2767R0, but not resolved by it.
Proposed resolution: