Created on 2024-11-01.00:00:00 last changed yesterday
[ 2025-12-10 Status changed: Tentatively NAD → NAD. ]
[ 2025-10-23; Reflector poll; Status changed: New → Tentatively NAD. ]
The range concepts are over-constrained by design, and `indirect_unary_invocable` always required invocability with `iter_value_t`. The P2609 changes enforced this requirement properly for iterators returning proxy references, including `zip_iterator`.
The following use of `std::ranges::for_each` is valid before P2609R3 and invalid after that.
#include <algorithm>
#include <ranges>
#include <tuple>
using namespace std::ranges;
void f() {
int a[1];
auto fun = [](auto t) {
[[maybe_unused]] auto x = std::get<int&>(t);
};
for_each(views::zip(a), fun);
}
The reason is that, P2609R3 requires `fun` to be `invocable` with iter_value_t<I>&, which is tuple<int>& when `I` is `zip_view`'s iterator, and tuple<int>& doesn't support std::get<int&>(t) because there isn't a int& member.
P2609R3 argues that "The actual consequence on user code seems small", but I believe that this code pattern is common enough, and it hurts if we cannot use get<int&>(t) in the lambda body. Note that `for_each` doesn't actually call `fun` with iter_value_t<I>, as can be seen by adding an explicit return type to `fun`. Did LWG foresee this impact of P2609R3? Could P2609R3 be reverted to unbreak this code pattern?| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2025-12-10 23:00:58 | admin | set | messages: + msg15800 |
| 2025-10-23 09:34:52 | admin | set | messages: + msg15368 |
| 2025-10-23 09:34:52 | admin | set | status: new -> nad |
| 2024-11-01 00:00:00 | admin | create | |