P2881 proposes a new way to build iterators, similar to generators but with less performance overhead and better nesting (and hence composability):

struct generator123
{
    auto operator()(auto&& sink) const
    {
        std::control_flow flow;

        // With P2561: sink(1)??;
        flow = sink(1);
        if (!flow) return flow;

        // With P2561: sink(2)??;
        flow = sink(2);
        if (!flow) return flow;

        return sink(3);
    }
};

int main() {
    for (int x : generator123()) // x iterates 1, 2, 3
    {
        std::print("{}\n", x);
        if (x == 2)
            break;
    }
}

While the benefits are undisputable, it’s quite verbose without P2561 and I feel C++ is starting to have too many different iterator models.

What do you think?

One of the authors has a nice presentation about pitfalls of ye olde for loops, which was probably a big motivator too: https://www.youtube.com/watch?v=95uT0RhMGwA