Текущая реализация Boost 1.55 предлагает два вида однонаправленные сопрограммы. Одним из них является тип pull, который является сопрограммой, которая не принимает параметров и возвращает значение в основной контекст; другой — push-тип, который представляет собой сопрограмму, которая принимает параметр из основного контекста, но не возвращает значения.
Как я могу объединить эти два для создания двунаправленной сопрограммы, которая принимает параметр и возвращает значение? На первый взгляд кажется, что это возможно, но я не могу понять, как это сделать с помощью строительных блоков, которые у меня есть в boost::coroutine
, Раньше двунаправленная сопрограмма была в более старых бустах, но теперь она устарела и не имеет документов, поэтому я не должен на нее полагаться.
т.е. я хотел бы что-то аналогичное этому:
void accumulate( pull_func &in, push_func &out )
{
int x = 0;
while ( in )
{
x += in.get() ; // transfers control from main context
out(x); // yields control to main context
}
}
void caller( int n )
{
bidirectional_coro( accumulate );
for ( int i = 0 ; i < n ; ++i )
{
int y = accumulate(i);
printf( "%d ", y ); // "0 1 3 6 10" etc
}
}
Фактически, сопрограмма наддува была двунаправленной, когда впервые была включена в надстройку (я думаю, 1.53).
http://www.boost.org/doc/libs/1_53_0_beta1/libs/coroutine/doc/html/coroutine/coroutine.htm
Этот код все еще должен быть совместим с самой последней версией boost, с незначительными изменениями, если что-нибудь.
Также вы можете напрямую использовать boost :: context для создания собственного класса сопрограмм.
http://www.boost.org/doc/libs/1_55_0/libs/context/doc/html/index.html
Параметр ‘intptr_t vp’ в fcontext_swap можно использовать для передачи значений / указателей вперед и назад, или вы можете хранить значения в самой сопрограмме, поскольку переменные-члены вашего класса сопрограмм должны быть допустимы в обоих контекстах.
редактировать:
Короткий ответ на ваш оригинальный вопрос — нет. То, что вы просите, не может быть сделано. Каждая сопрограмма имеет свой собственный стек и контекст, которые недоступны из других экземпляров сопрограммы. Кроме того, когда вы переходите в контекст сопрограммы, состояние вызывающего контекста сохраняется в тот экземпляр сопрограммы, и возврат к исходному контексту может быть сделан только путем вызова аргумента, который тот сопрограмма перешла в вашу функцию.
Но переменные, объявленные вне локальной области действия сопрограммы, будут действительны как внутри, так и вне функции сопрограммы. Таким образом, вы можете использовать coroutine :: push_type и вставить указатель вместо значения. Вы можете использовать значение, а затем изменить его, прежде чем вернуться к исходному контексту.
Кроме того, вы можете безопасно передавать указатели на локальные переменные в сопрограмму, поскольку они не будут уничтожены, пока вы не выпрыгнете из сопрограммы и не выполните область вызова до завершения.
Вы можете посмотреть на пример, содержащийся в boost.coroutine
https://github.com/boostorg/coroutine/blob/master/example/cpp03/chaining.cpp