最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c++20 - What do I use in C++ instead of IEnumerable<T> for the return type of a co_yield function? - Stack Overflo

programmeradmin5浏览0评论

In C#, I can write the following code:

IEnumerable<int> evenUpTo(int max)
{
    for (int i = 0; i < max; i += 2)
    {
        yield return i;
    }
}

foreach(int e in evenUpTo(11))
{
    Console.WriteLine(e);
}

And the compiler will generate a class for me, which satisfies the IEnumerable<int> interface.

Now, C++20 got coroutines as well. In principle, the code looks very similar:

#include <print>
#include <coroutine>

??? evenUpTo(int max) {
    for (int i = 0; i < max; i += 2) {
        co_yield i;
    }
}

int main() {
    for (auto e : evenUpTo(11)) {
        std::print("{0}\n", e);
    }
}

What do I put as the return type ????

I read that IEnumerable isn't needed in C++, because C++ has iterators. A pair of iterators (.begin() and .end()) is certainly enough to get a range-based for-loop working. But which container would I use? But linked question is from 2012 and coroutines are from C++20, so this topic hasn't been covered.

I can probably write my own Generator<T> template, but I'd like to avoid that, if there is a built-in STL type.

In C#, I can write the following code:

IEnumerable<int> evenUpTo(int max)
{
    for (int i = 0; i < max; i += 2)
    {
        yield return i;
    }
}

foreach(int e in evenUpTo(11))
{
    Console.WriteLine(e);
}

And the compiler will generate a class for me, which satisfies the IEnumerable<int> interface.

Now, C++20 got coroutines as well. In principle, the code looks very similar:

#include <print>
#include <coroutine>

??? evenUpTo(int max) {
    for (int i = 0; i < max; i += 2) {
        co_yield i;
    }
}

int main() {
    for (auto e : evenUpTo(11)) {
        std::print("{0}\n", e);
    }
}

What do I put as the return type ????

I read that IEnumerable isn't needed in C++, because C++ has iterators. A pair of iterators (.begin() and .end()) is certainly enough to get a range-based for-loop working. But which container would I use? But linked question is from 2012 and coroutines are from C++20, so this topic hasn't been covered.

I can probably write my own Generator<T> template, but I'd like to avoid that, if there is a built-in STL type.

Share Improve this question asked Mar 15 at 19:18 Thomas WellerThomas Weller 59.9k23 gold badges137 silver badges254 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 8

C++23

C++23 now has the std::generator<> template, which you get with #include <generator>.

#include <print>
#include <coroutine>
#include <generator>

std::generator<int> evenUpTo(int max) {
    for (int i = 0; i < max; i += 2) {
        co_yield i;
    }
}

int main() {
    for (auto e : evenUpTo(11)) {
        std::print("{0}\n", e);
    }
}

Compiler Explorer: https://godbolt./z/s66jbq9c7

C++20

Reiner Grimm explains how to write your own template in the book Concurrency with Modern C++ [Amazon]. There's an updated version by Roger Voss available on Github.

There's also a the reference implementation [Github] of the proposal P2168 which suggests to introduce the synchronous std::generator to C++23.

发布评论

评论列表(0)

  1. 暂无评论