|
| 1 | +<?xml version='1.0' encoding='utf-8' standalone='no'?> |
| 2 | +<!DOCTYPE issue SYSTEM "lwg-issue.dtd"> |
| 3 | + |
| 4 | +<issue num="4171" status="New"> |
| 5 | +<title>P2609R3 breaks code that uses `views::zip` and <tt>get<T></tt></title> |
| 6 | +<section><sref ref="[indirectcallable.indirectinvocable]"/></section> |
| 7 | +<submitter>S. B. Tam</submitter> |
| 8 | +<date>01 Nov 2024</date> |
| 9 | +<priority>99</priority> |
| 10 | + |
| 11 | +<discussion> |
| 12 | +<p> |
| 13 | +The following use of `std::ranges::for_each` is valid before <paper num="P2609R3"/> and invalid after that. |
| 14 | +</p> |
| 15 | +<blockquote><pre> |
| 16 | +#include <algorithm> |
| 17 | +#include <ranges> |
| 18 | +#include <tuple> |
| 19 | +using namespace std::ranges; |
| 20 | + |
| 21 | +void f() { |
| 22 | + int a[1]; |
| 23 | + auto fun = [](auto t) { |
| 24 | + [[maybe_unused]] auto x = std::get<int&>(t); |
| 25 | + }; |
| 26 | + for_each(views::zip(a), fun); |
| 27 | +} |
| 28 | +</pre></blockquote> |
| 29 | +<p> |
| 30 | +The reason is that, <paper num="P2609R3"/> requires `fun` to be `invocable` with <tt>iter_value_t<I>&</tt>, |
| 31 | +which is <tt>tuple<int>&</tt> when `I` is `zip_view`'s iterator, and <tt>tuple<int>&</tt> |
| 32 | +doesn't support <tt>std::get<int&>(t)</tt> because there isn't a <tt>int&</tt> member. |
| 33 | +<p/> |
| 34 | +P2609R3 argues that "The actual consequence on user code seems small", but I believe that this code pattern is |
| 35 | +common enough, and it hurts if we cannot use <tt>get<int&>(t)</tt> in the lambda body. |
| 36 | +<p/> |
| 37 | +Note that `for_each` doesn't actually call `fun` with <tt>iter_value_t<I></tt>, as can be seen by adding |
| 38 | +an explicit return type to `fun`. |
| 39 | +<p/> |
| 40 | +Did LWG foresee this impact of <paper num="P2609R3"/>? Could P2609R3 be reverted to unbreak this code pattern? |
| 41 | +</p> |
| 42 | +</discussion> |
| 43 | + |
| 44 | +<resolution> |
| 45 | +</resolution> |
| 46 | +</issue> |
0 commit comments