如何在 C++ 中实现生成器?

发布于 2024-08-04 05:49:14 字数 82 浏览 2 评论 0原文

我想知道如何在 C++ 中实现像 Python 这样的生成器? Python 可以使用关键字“yield”来做到这一点。 但在 C++ 中如何实现呢?

I want to know how to implement a generator , like Python, in C++?
Python can use keyword "yield" to do so.
But how to do it in C++?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

回梦 2024-08-11 05:49:14

详细说明迭代器实现:这是一个示例。它可以用作循环变量,或在 std 算法中。

#include <iterator>

template< typename T, typename TDiff = T >
struct TGenerator : public std::iterator<std::forward_iterator_tag,T,TDiff> {
  T from,to;
  T value;
  TDiff step;
  bool issentinel;

  TGenerator( T from, T to, TDiff step, bool sentinel = false )
    : from(from),to(to),step(step),issentinel(sentinel), value(from)
  {}

  void operator++(){ value += step; }

  const T& operator*()const { return value; }

  bool operator!=( const TGenerator& other ) const {
    return value<to;
  }

  TGenerator sentinel()const { return TGenerator(0,0,0,true); }

};


#include <algorithm>
#include <iostream>

int main()
{
  TGenerator<int> i(0,10,3);
  std::copy( i, i.sentinel(), std::ostream_iterator<int>( std::cout, " " ) );

    return 0;
}

To elaborate on the iterator implementation: this is an example. It can be used as a loop variable, or in std algorithms.

#include <iterator>

template< typename T, typename TDiff = T >
struct TGenerator : public std::iterator<std::forward_iterator_tag,T,TDiff> {
  T from,to;
  T value;
  TDiff step;
  bool issentinel;

  TGenerator( T from, T to, TDiff step, bool sentinel = false )
    : from(from),to(to),step(step),issentinel(sentinel), value(from)
  {}

  void operator++(){ value += step; }

  const T& operator*()const { return value; }

  bool operator!=( const TGenerator& other ) const {
    return value<to;
  }

  TGenerator sentinel()const { return TGenerator(0,0,0,true); }

};


#include <algorithm>
#include <iostream>

int main()
{
  TGenerator<int> i(0,10,3);
  std::copy( i, i.sentinel(), std::ostream_iterator<int>( std::cout, " " ) );

    return 0;
}
沙与沫 2024-08-11 05:49:14

你确实做不到,但你可以假装做到。这是一种用 C 语言伪造它的方法,你可以使用它在 C++ 中也是如此。

You can't do it, really, but you can fake it. Here's a way you can fake it in C, which you can use in C++ as well.

音盲 2024-08-11 05:49:14

多次调用协程并获得不同的答案意味着您可以保留某种状态。保持状态的方式是对象。让它们看起来像函数调用的方法是运算符重载。有关一些示例,请参阅函数对象维基百科中的文章。

Calling a coroutine multiple times and getting different answers means you keep some state. The way to keep a state is objects. The way to make them look like function call is operator overloading. For some examples see the function object article in Wikipedia.

夜无邪 2024-08-11 05:49:14

你可以使用 boost.context (抱歉,还没有在 boost 发行版上,你必须从 提升库)。

典型的示例代码如下:

#include <iostream>
#include <boost/context.hpp>

using namespace std;

struct Parameters {
  int par1;
  float par2;
};

boost::context c1;
boost::context c2;

void F(void* parameters) {
  Parameters& pars = *(Parameters*)parameters;
  cout << pars.par1 << endl;
  c2.jump_to(c1);
  cout << pars.par2 << endl;
};

int main() {
  c1 = boost::context::current();
  Parameters p;
  p.par1 = 8;
  c2 = boost::context::create_context( F , c1 , p );
  c1.jump_to(c2);
  p.par2 = 1.3;
  c1.jump_to(c2);
}

you can use boost.context (sorry, not on boost distribution yet, you'll have to get it from boost vault).

A typical example code would be like this:

#include <iostream>
#include <boost/context.hpp>

using namespace std;

struct Parameters {
  int par1;
  float par2;
};

boost::context c1;
boost::context c2;

void F(void* parameters) {
  Parameters& pars = *(Parameters*)parameters;
  cout << pars.par1 << endl;
  c2.jump_to(c1);
  cout << pars.par2 << endl;
};

int main() {
  c1 = boost::context::current();
  Parameters p;
  p.par1 = 8;
  c2 = boost::context::create_context( F , c1 , p );
  c1.jump_to(c2);
  p.par2 = 1.3;
  c1.jump_to(c2);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文