[Bug c++/102418] New: [concepts] prefer iterator to range concept failures in ranges (QoI)

ldalessandro at gmail dot com gcc-bugzilla@gcc.gnu.org
Mon Sep 20 19:45:58 GMT 2021


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102418

            Bug ID: 102418
           Summary: [concepts] prefer iterator to range concept failures
                    in ranges (QoI)
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ldalessandro at gmail dot com
  Target Milestone: ---

When interacting with the ranges library I am occasionally presented with
hundreds of lines of circuitous concept failures driven by failing a range
concept. The vast majority of programmers won't find these helpful.

On the other hand, it was pointed out that when the failure is due to one of
the range's dependent iterator concepts, asserting the corresponding iterator
concept produces beautiful and too-the-point failure traces.

>From a QoI perspective, some mechanism to prioritize the iterator concept
failure when it is responsible for a range concept failure would go a long way
to making ranges more usable.

The example I was playing with is at https://godbolt.org/z/fGWcTdEjo, an is the
difference in output when -DITERATOR is defined in the following example.

```
struct Broken {
    struct iterator {
        int i;
        auto operator*() const -> decltype(auto) {
            return std::tie(i);
        }
        auto operator++() -> decltype(auto) {
            ++i;
            return *this;
        }
        friend bool operator==(iterator const&, iterator const&) = default;
        friend auto operator<=>(iterator const&, iterator const&) = default;
    };

    auto begin() const -> iterator { return {}; }
    auto end() const -> iterator { return {}; }
};

#ifdef ITERATOR
static_assert(std::input_iterator<Broken::iterator>);
#else

#include <cstdio>

int foo() {
    Broken r;
    std::ranges::for_each(r, [](auto t) { 
        auto [i] = t;
        printf("%d\n", i);
    });
}
#endif
```


More information about the Gcc-bugs mailing list