【问题标题】:C++20 Coroutines and iostreamC++20 协程和 iostream
【发布时间】:2021-04-29 19:38:49
【问题描述】:

我正在玩 C++ 20 的协程。示例使用 clang++ 编译。

我面临的编译器错误是

错误:二进制表达式的操作数无效('std::ostream'(又名 'basic_ostream') 和 'cppcoro::generator')

大概是下面一行

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

截取的完整代码如下所示:

#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;
}

可在此处找到截断的可执行代码: https://godbolt.org/z/4cxhqxPP7

【问题讨论】:

  • 我第一次看到协同程序在起作用。我看了一下标题,我可以理解基于范围的循环是如何工作的,但是为什么std::cout &lt;&lt; numbers &lt;&lt; " "; 应该工作,我不明白。您是否有一些参考资料表明这应该没问题?
  • 这篇文章可能会像其他语言一样使用cout &lt;&lt; numbers()。这是错误的(专门针对这种生成器类型;另一个可以支持),但可能这就是意图。

标签: c++ iostream clang++ c++-coroutine


【解决方案1】:

根据cppcoro::generator 的文档,您可以对生成器执行的唯一“有意义”操作是通过begin()end() 获取开始和结束迭代器。这正是您第二次使用for (auto n : generatorForNumbers(0, 5)) 有效的原因。它遍历生成器。虽然您在技术上遇到了未定义的行为,因为生成器没有停止条件,因此它会溢出 int

您不能直接打印生成器。你必须迭代它。所以你可以这样做:

auto numbers = generatorForNumbers(-10);

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

或更好(在我看来):

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

甚至更好地使用范围(感谢 cmets 中的@cigien):

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

【讨论】:

  • for (auto n : generatorForNumbers(-10) | std::views::take(20)) 我认为应该也能正常工作。
  • 看起来很不错,谢谢。仍然没有 gcc 支持,不是吗?
  • @cigien 好多了!我自己没有玩过范围,所以我不熟悉如何使用它们
猜你喜欢
  • 2022-07-22
  • 2020-01-22
  • 2020-02-26
  • 2017-09-16
  • 2021-12-27
  • 2019-10-04
  • 2021-09-03
  • 2019-12-01
  • 2021-01-28
相关资源
最近更新 更多