This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of WP status.
ranges::generate_random
's helper lambda should specify the return typeSection: 26.12.2 [alg.rand.generate] Status: WP Submitter: Hewill Kang Opened: 2024-04-28 Last modified: 2024-11-28
Priority: 2
View all other issues in [alg.rand.generate].
View all issues with WP status.
Discussion:
The non-specialized case of generate_random(r, g, d)
would call
ranges::generate(r, [&d, &g] { return invoke(d, g); })
.
However, the lambda does not explicitly specify the return type, which leads
to a hard error when invoke
returns a reference to the object that is not copyable or
R
is not the output_range
for decay_t<invoke_result_t<D&, G&>>
.
Previous resolution [SUPERSEDED]:
This wording is relative to N4981.
Modify 26.12.2 [alg.rand.generate] as indicated:
template<class R, class G, class D> requires output_range<R, invoke_result_t<D&, G&>> && invocable<D&, G&> && uniform_random_bit_generator<remove_cvref_t<G>> constexpr borrowed_iterator_t<R> ranges::generate_random(R&& r, G&& g, D&& d);-5- Effects:
(5.1) — […]
(5.2) — […]
(5.3) — Otherwise, calls:
ranges::generate(std::forward<R>(r), [&d, &g] -> decltype(auto) { return invoke(d, g); });-6- Returns:
ranges::end(r)
-7- Remarks: The effects of
generate_random(r, g, d)
shall be equivalent toranges::generate(std::forward<R>(r), [&d, &g] -> decltype(auto) { return invoke(d, g); })
[2024-05-12, Hewill Kang provides improved wording]
[2024-08-02; Reflector poll]
Set priority to 2 after reflector poll.
[2024-10-09; LWG telecon: Move to Ready]
[Wrocław 2024-11-23; Status changed: Voting → WP.]
Proposed resolution:
This wording is relative to N4981.
Modify 29.5.2 [rand.synopsis], header <random>
synopsis, as indicated:
#include <initializer_list> // see 17.10.2 [initializer.list.syn] namespace std { […] namespace ranges { […] template<class R, class G, class D> requires output_range<R, invoke_result_t<D&, G&>> && invocable<D&, G&> && uniform_random_bit_generator<remove_cvref_t<G>> && is_arithmetic_v<invoke_result_t<D&, G&>> constexpr borrowed_iterator_t<R> generate_random(R&& r, G&& g, D&& d); template<class G, class D, output_iterator<invoke_result_t<D&, G&>> O, sentinel_for<O> S> requires invocable<D&, G&> && uniform_random_bit_generator<remove_cvref_t<G>> && is_arithmetic_v<invoke_result_t<D&, G&>> constexpr O generate_random(O first, S last, G&& g, D&& d); } […] }
Modify 26.12.2 [alg.rand.generate] as indicated:
template<class R, class G, class D> requires output_range<R, invoke_result_t<D&, G&>> && invocable<D&, G&> && uniform_random_bit_generator<remove_cvref_t<G>> && is_arithmetic_v<invoke_result_t<D&, G&>> constexpr borrowed_iterator_t<R> ranges::generate_random(R&& r, G&& g, D&& d);-5- Effects:
[…]template<class G, class D, output_iterator<invoke_result_t<D&, G&>> O, sentinel_for<O> S> requires invocable<D&, G&> && uniform_random_bit_generator<remove_cvref_t<G>> && is_arithmetic_v<invoke_result_t<D&, G&>> constexpr O ranges::generate_random(O first, S last, G&& g, D&& d);-8- Effects: Equivalent to:
[…]