Issue 3187: P0591R4 reverted DR 2586 fixes to scoped_allocator_adaptor::construct() (original) (raw)
This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++20 status.
3187. P0591R4 reverted DR 2586 fixes to scoped_allocator_adaptor::construct()
Section: 20.2.8.2 [allocator.uses.construction] Status: C++20 Submitter: Jonathan Wakely Opened: 2019-02-14 Last modified: 2021-02-25
Priority: Not Prioritized
View all other issues in [allocator.uses.construction].
View all issues with C++20 status.
Discussion:
2586(i) fixed the value category in the uses-allocator checks done by scoped_allocator_adaptor. When we made that use uses_allocator_construction_args we reintroduced the problem, because that function has the same bug.
#include
struct X { using allocator_type = std::allocator; X(std::allocator_arg_t, allocator_type&&) { } X(const allocator_type&) { } };
int main() { std::allocator a; std::make_obj_using_allocator(a); }
This will fail to compile, because uses_allocator_construction_args will check is_constructibleusing an rvalue allocator, but then return tuple<allocator_arg_t, const allocator<X>&>containing an lvalue allocator. Those args cannot be used to construct an X.
[2019-02; Kona Wednesday night issue processing]
Status to Ready
Proposed resolution:
This wording is relative to N4800.
- Change 20.2.8.2 [allocator.uses.construction] as indicated:
[Drafting Note: Arguably the
uses_allocatorspecialization should also useconst Alloc&but in practice that doesn't matter, except for even more contrived cases than the very contrived example above.]
template <class T, class Alloc, class... Args>
auto uses_allocator_construction_args(const Alloc& alloc, Args&&... args) -> see below;[…]
-5- Returns: A
tuplevalue determined as follows:- (5.1) — If
uses_allocator_v<T, Alloc>isfalseandis_constructible_v<T, Args...>istrue, returnforward_as_tuple(std::forward<Args>(args)...). - (5.2) — Otherwise, if
uses_allocator_v<T, Alloc>istrueandis_constructible_v<T, allocator_arg_t, const Alloc&, Args...>istrue, returntuple<allocator_arg_t, const Alloc&, Args&&...>(
allocator_arg, alloc, std::forward(args)...) - (5.3) — Otherwise, if
uses_allocator_v<T, Alloc>istrueandis_constructible_v<T, Args..., const Alloc&>istrue, returnforward_as_tuple(std::forward<Args>(args)..., alloc). - (5.4) — Otherwise, the program is ill-formed.
[…]
- (5.1) — If