C#中C++的C++相当于?

Gui*_*e07 30 c++

public void Consumer()
{
    foreach(int i in Integers())
    {
        Console.WriteLine(i.ToString());
    }
}

public IEnumerable<int> Integers()
{
    yield return 1;
    yield return 2;
    yield return 4;
    yield return 8;
    yield return 16;
    yield return 16777216;
}
Run Code Online (Sandbox Code Playgroud)

有没有办法用模板技巧(或其他)在c ++中获得相同的语法?

Łuk*_*ski 26

看看boost :: Coroutine.它做你想要的. http://www.crystalclearsoftware.com/soc/coroutine/index.html#coroutine.intro

教程示例

http://www.crystalclearsoftware.com/soc/coroutine/coroutine/tutorial.html

int range_generator(generator_type::self& self, int min, int max) 
 {
   while(min < max)
     self.yield(min++);
   self.exit();
 }
Run Code Online (Sandbox Code Playgroud)

  • 如果这是针对Win32的,请,请理解在*any*代码中使用Fibers是一个非常高级的主题,并且看到有效隐藏光纤代码的库真的很可怕.有一大堆Win32 API,它们在Fibers存在的情况下不起作用,或者更多的scally不能按预期工作.例如,Win32中的锁是基于线程ID - 这意味着对于Fibers,如果你采取锁定然后屈服,在你的线程上运行的另一个光纤也可以成功地获取锁定!因此,除非你非常小心,否则它会让你很难受. (5认同)
  • +1,这真的很有趣,而且我很少/不知道`self.exit()`是一个返回语句的合法替代品.(我怀疑这是一些可怕的例外滥用或'longjmp`,但我不确定我想知道!) (2认同)
  • Boost.Coroutine在汇编中实现,并通过支持"Fibers"的平台上的OS调用实现.它没有在纯C++中实现. (2认同)

Mat*_* M. 10

您可以随时手动编码.说实话,yield对我来说真的好像糖涂层(以及合作例程).

那是一个协程,真的吗?一些州捆绑在一起:

  • 一个创建它的函数(它不是一个构造函数吗?)
  • 一个函数移动到下一个状态(传统上不是操作符++吗?)

在C++中,它被称为an InputIterator,并且可以任意胖.

所以,确实语法不会那么漂亮,但这应该做,只需使用标准库:

static std::array<int, 6> const Array = {{1, 2, 4, 8, 16, 16777216}};

class Integers: public std::iterator<std::input_iterator_tag,
                                      int, ptrdiff_t, int const*, int>
{
public:
  Integers(): _index(0) {}

  operator bool() const { return _index < Array.size(); }

  Integers& operator++() { assert(*this); ++_index; return *this; }
  Integers operator++(int) { Integers tmp = *this; ++*this; return tmp; }

  int operator*() const { assert(*this); return Array[_index]; }
  int const* operator->() const { assert(*this); return &Array[_index]; }

private:
  size_t _index;
}; // class Integers
Run Code Online (Sandbox Code Playgroud)

很明显,既然确切地确定了存储的状态,你决定是否所有状态都是预先计算的,或者部分(或整个部分)是否被懒惰地计算,并且可能是缓存的,并且可能是多线程的,并且......你得到了想法:)

  • 我不明白为什么"糖衣"是如此糟糕.如果你去做它,一个类也只不过是糖衣,同样适用于循环等等.手动方法的明显问题是,你基本上必须编写一个任意复杂的状态机(我可以想到几个真实世界的应用程序,这不会那么容易) (25认同)
  • 我不同意"引入复杂性" - 根据我的经验,生成器语义简单易懂(如果有一种语言不遵循"最简单的语法"方法,那就是c ++!).它也不是C#语法,而是CS中众所周知的概念,用很多语言实现(当然和InputIterator不一样!).手动为某些功能实现状态机在很多情况下非常重要.例如,尝试使用InputerIterator实现[this](http://snippets.dzone.com/posts/show/753) - 当然难以理解 (14认同)
  • @Voo:糖衣涂层引入复杂性,简单地说 - >还有更多需要学习的地方.OP在C++中询问了`yield`,我认为不是将C#语法"移植"到C++中,而是最好反思它在做什么,并找到C++中的惯用语.协同例程不过是一个`InputIterator`. (3认同)
  • Matthieu,什么是'for`循环,但在'while`循环中涂糖?什么是`switch`但是`if`的级联?句法糖并不一定是坏事,因为没有它我们仍然会将十六进制操作码直接打入内存.这只是你画线的问题.你似乎把它画在只有一个循环语句加一个分支语句和一个包含`yield`的语言的语言之间.其他包括`yield`.我,我已经习惯了,并且看到了它的重点,但无论有没有它都可以生存. (2认同)

Fen*_*ang 9

在C++ 14中,您可以这样模仿yield:

auto&& function = []() { 
    int i = 0; 
    return [=]() mutable { 
        int arr[] = {1,2,4,8,16,16777216}; 
        if ( i < 6 ) 
            return arr[i++]; 
        return 0; 
    }; 
}();
Run Code Online (Sandbox Code Playgroud)

http://ideone.com/SQZ1qZ上提供了一个实例

  • 难道 `yield` 的目的不是为了防止一系列对象(本例中为 `int[]`)被立即放入内存吗? (6认同)
  • 我没有,但现场示例可以轻松适应您的答案,而无需显示来自 ideone.com 的广告。 (2认同)

Duk*_*ing 7

协程都在C ++ 20草案和用途co_yield代替yield

另请参阅:什么是 C++20 中的协程?

第一个链接中有一些示例用法:(第二个可能是您正在寻找的)