简体   繁体   English

C++20 协程和 iostream

[英]C++20 Coroutines and iostream

I am playing around with C++ 20's Coroutines.我正在玩 C++ 20 的协程。 The sample is compiled with clang++.该示例使用 clang++ 编译。

The compiler error I am facing is我面临的编译器错误是

error: invalid operands to binary expression ('std::ostream' (aka 'basic_ostream') and 'cppcoro::generator')错误:二进制表达式的操作数无效(“std::ostream”(又名“basic_ostream”)和“cppcoro::generator”)

which is about the following line这是关于以下行

std::cout << numbers << " ";  

the full code snipped looks like this:截断的完整代码如下所示:

#include <thread>
#include <iostream>
#include <vector>
#include <cppcoro/generator.hpp>

using namespace std;

// coroutine
cppcoro::generator<int> generatorForNumbers(int begin, int inc = 1) 
{
  // for Schleife ohne Abbruchbedingung
  for (int i = begin;; i += inc) 
  {
    co_yield i;
  }  
}

int main() 
{

    auto numbers = generatorForNumbers(-10);                 
  
    for (int i= 1; i <= 20; ++i)
    {
        std::cout << numbers << " ";       
    }
  
    std::cout << "\n\n";
        
    // inline works
    for (auto n: generatorForNumbers(0, 5))
    {
        std::cout << n << " ";  
    }

    std::cout << std::endl;
}

Executable code snipped can be found here: https://godbolt.org/z/4cxhqxPP7可在此处找到截断的可执行代码: https://godbolt.org/z/4cxhqxPP7

From the documentation of cppcoro::generator , the only "meaningful" operations you can do to a generator is get begin and end iterators via begin() and end() .cppcoro::generator的文档中,您可以对生成器执行的唯一“有意义”操作是通过begin()end()获取开始和结束迭代器。 This is precisely why your second use for (auto n: generatorForNumbers(0, 5)) works.这正是您第二次使用for (auto n: generatorForNumbers(0, 5))有效的原因。 It iterates over the generator.它遍历生成器。 Though you technically hit undefined behavior since there's no stopping condition for the generator so it overflows an int .尽管您在技术上遇到了未定义的行为,因为生成器没有停止条件,因此它会溢出int

You can't print the generator directly.您不能直接打印生成器。 You have to iterate over it.你必须迭代它。 So you could do this instead:所以你可以这样做:

auto numbers = generatorForNumbers(-10);

auto it = numbers.begin();
for (int i= 1; i <= 20; ++i)
{
    std::cout << *it << " ";
    ++it;
}

or better (in my opinion):或更好(在我看来):

int i = 0;
for (auto n : generatorForNumbers(-10))
{
    if (++i > 20)
        break;
    std::cout << n << " ";
}

or even better using ranges (thanks to @cigien in the comments):甚至更好地使用范围(感谢评论中的@cigien):

for (auto n : generatorForNumbers(-10) | std::views::take(20))
{
    std::cout << n << " ";
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM