This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.

3864. zip over range of reference to an abstract type

Section: 26.7.24 [] Status: New Submitter: Barry Revzin Opened: 2023-01-28 Last modified: 2023-02-06

Priority: 4

View all issues with New status.



#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.

On the other hand, 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: