tuple-for-each
can call user-defined operator,
Section: 25.7.25.2 [range.zip.view] Status: C++23 Submitter: Nicole Mazzuca Opened: 2022-08-26 Last modified: 2023-11-22
Priority: Not Prioritized
View all other issues in [range.zip.view].
View all issues with C++23 status.
Discussion:
The specification for tuple-for-each
is:
template<class F, class Tuple> constexpr auto tuple-for-each(F&& f, Tuple&& t) { // exposition only apply([&]<class... Ts>(Ts&&... elements) { (invoke(f, std::forward<Ts>(elements)), ...); }, std::forward<Tuple>(t)); }
Given
struct Evil { void operator,(Evil) { abort(); } };
and tuple<int, int> t
, then
tuple-for-each([](int) { return Evil{}; }, t)
,
the program will (unintentionally) abort.
It seems likely that our Evil
's operator,
should not be called.
[2022-09-23; Reflector poll]
Set status to Tentatively Ready after nine votes in favour during reflector poll.
Feedback from reviewers:
"NAD. This exposition-only facility is only used with things that return
void
. As far as I know, users can't defineoperator,
forvoid
." "If I see thevoid
cast, I don't need to audit the uses or be concerned that we'll add a broken use in the future."
[2022-11-12 Approved at November 2022 meeting in Kona. Status changed: Voting → WP.]
Proposed resolution:
This wording is relative to the forthcoming C++23 CD.
Modify [range.adaptor.tuple] as indicated:
template<class F, class Tuple> constexpr auto tuple-for-each(F&& f, Tuple&& t) { // exposition only apply([&]<class... Ts>(Ts&&... elements) { (static_cast<void>(invoke(f, std::forward<Ts>(elements))), ...); }, std::forward<Tuple>(t)); }