zip
over range of reference to an abstract typeSection: 25.7.25 [range.zip] Status: New Submitter: Barry Revzin Opened: 2023-01-28 Last modified: 2023-02-06
Priority: 4
View all issues with New status.
Discussion:
Consider:
#include <ranges> struct Abstract { virtual ~Abstract() = default; virtual int f() = 0; }; struct Concrete : Abstract { int f() override { return 42; } }; int main() { Concrete c[10]; auto xformed = c | std::views::transform([](Concrete& c) -> Abstract& { return c; }); for (Abstract& a : xformed) { } // ok auto zipped = std::views::zip(xformed); for (auto&& [a] : zipped) { } // error }
Here, xformed
is a range whose reference type is Abstract&
and whose value_type
is Abstract
.
Even though you can't actually create a value of that value_type
, that's okay here, because no code is actually trying to do so.
zipped
is a range whose reference type is std::tuple<Abstract&>
and whose
value_type
is std::tuple<Abstract>
. No code here is actually trying to construct a value_type
either,
but this code fails because simply instantiating std::tuple<Abstract>
is an error. There's no other possible
value_type
for zipped
to have, std::tuple<Abstract>
is correct — it's just that it happens
to be an ill-formed type in this context. There are workarounds for this case — you would have to make xformed
be a range of Abstract*
or, probably better, a range of reference_wrapper<Abstract>
instead.
This is unfortunate because many (most?) algorithms don't actually make any use of a range's value_type
. The ones that do
(like ranges::min
) obviously could not work, but currently we end up rejecting all uses. Probably the only possible way to
make this work is to allow value_type
to be void
(or absent), but it is currently a fairly fundamental type due
to its use in indirectly_readable
to identify input iterators.
[2023-02-06; Reflector poll]
Set priority to 4 after reflector poll.
Several votes for NAD. Maybe tuple<Abstract>
should be
explicitly made ill-formed (currently seems underspecified) or should be
"disabled" like invalid hash
specializations and formatters.
Proposed resolution: