Skip to content

Commit 62064a0

Browse files
committed
Issue discussion redrafted and improved by submitter
1 parent f34b82a commit 62064a0

File tree

1 file changed

+79
-6
lines changed

1 file changed

+79
-6
lines changed

xml/issue4313.xml

Lines changed: 79 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,86 @@
1212

1313
<discussion>
1414
<p>
15-
<paper num="P0591R4"/> updated the definition of uses-allocator construction to specially handle `pair`.
16-
Per <sref ref="[tuple.cnstr]"/>/33, it seems that the `allocator_arg_t` constructors should also be
17-
updated to handle `pair`. However, such a change doesn't seem intended in <paper num="P0591R4"/>,
18-
and it would significantly complicate tuple. Currently, implementations consistently don't update
19-
these constructors in C++20.
15+
Before <paper num="P0591R4"/>, only `scoped_allocator_adaptor::construct` and
16+
`polymorphic_allocator::construct` specially handled `pair` for the purpose of uses-allocator
17+
construction. The primary definition of uses-allocator construction (in e.g.,
18+
<paper num="N4659"/> [allocator.uses.construction]) did not specially handle `pair`.
19+
The `allocator_arg_t` constructors of `tuple`, which were specified to construct `tuple`
20+
elements with uses-allocator constructor (per e.g., <paper num="N4659"/> [tuple.cnstr] p26),
21+
did not specially handle `pair` either.
2022
<p/>
21-
Perhaps we should explicitly say that the `allocator_arg_t` constructors don't specially handle `pair`.
23+
<paper num="P0591R4"/> redefined uses-allocator construction in terms of `make_obj_using_allocator`
24+
in [allocator.uses.construction] p1 as:
25+
</p>
26+
<blockquote style="border-left: 3px solid #ccc;padding-left: 15px;">
27+
<p>
28+
When applied to the construction of an object of type `T`, it is equivalent to initializing it
29+
with the value of the expression <tt>make_obj_using_allocator&lt;T&gt;(alloc, args...)</tt>, described below.
30+
</p>
31+
</blockquote>
32+
<p>
33+
And the new definition does handle `pair`. As the specification of `allocator_arg_t` constructors of
34+
`tuple` (now in <sref ref="[tuple.cnstr]"/> p33) still refer to uses-allocator construction as-is,
35+
these constructors should construct a `pair` element in a way equivalent to `make_obj_using_allocator` now.
36+
<p/>
37+
The following example shows the behavioral difference.
38+
</p>
39+
<blockquote><pre>
40+
#include &lt;cstddef&gt;
41+
#include &lt;utility&gt;
42+
#include &lt;tuple&gt;
43+
#include &lt;memory&gt;
44+
#include &lt;vector&gt;
45+
#include &lt;cassert&gt;
46+
47+
template&lt;class T&gt;
48+
class payload_ator {
49+
int payload{};
50+
51+
public:
52+
using value_type = T;
53+
54+
payload_ator() = default;
55+
56+
constexpr explicit payload_ator(int n) noexcept : payload{n} {}
57+
58+
template&lt;class U&gt;
59+
constexpr explicit payload_ator(payload_ator&lt;U&gt; a) noexcept : payload{a.payload} {}
60+
61+
friend bool operator==(payload_ator, payload_ator) = default;
62+
63+
template&lt;class U&gt;
64+
friend constexpr bool operator==(payload_ator x, payload_ator&lt;U&gt; y) noexcept {
65+
return x.payload == y.payload;
66+
}
67+
68+
constexpr T* allocate(std::size_t n) { return std::allocator&lt;T&gt;{}.allocate(n); }
69+
70+
constexpr void deallocate(T* p, std::size_t n) { return std::allocator&lt;T&gt;{}.deallocate(p, n); }
71+
72+
constexpr int get_payload() const noexcept { return payload; }
73+
};
74+
75+
bool test() {
76+
constexpr int in_v = 42;
77+
using my_pair_t = std::pair&lt;int, std::vector&lt;int, payload_ator&lt;int&gt;&gt;&gt;;
78+
std::tuple&lt;my_pair_t&gt; t(std::allocator_arg, payload_ator&lt;int&gt;{in_v});
79+
auto out_v = std::get&lt;0&gt;(t).second.get_allocator().get_payload();
80+
return in_v == out_v;
81+
}
82+
83+
int main() {
84+
assert(test()); // <span style="color:#C80000;font-weight:bold">passes only if allocator_arg_t constructors of tuple specially handle pair</span>
85+
}
86+
</pre></blockquote>
87+
<p>
88+
However, the behavioral changes of these constructors were not discussed in <paper num="P0591R4"/>,
89+
and existing implementations that claim full implementation of <paper num="P0591R4"/> (MSVC STL and libstdc++)
90+
did not change these constructors (<a href="https://godbolt.org/z/6vnP78nqW">demo</a>).
91+
<p/>
92+
Given that implementations did not recognize changes of `allocator_arg_t` constructors as part of the paper,
93+
and special handling of `pair` would significantly complicate these constructors, perhaps we should
94+
explicitly specify that these constructors behave as if special handling for `pair` were missing.
2295
</p>
2396
</discussion>
2497

0 commit comments

Comments
 (0)