В статье о возобновляемые функции, в разделе об ограничениях перечислены три ограничения:
- Возобновляемые функции не могут использовать переменное количество аргументов. В ситуациях, когда необходимы переменные, развертывание аргументов может быть помещено в функцию, вызывающую возобновляемую функцию после выполнения развертывания аргументов.
- Тип возврата возобновляемой функции должен быть
future<T>
или жеshared_future<T>
, Ограничения на T определяются какstd::future
не это предложение, ноT
должен быть копируемого или подвижного типа, или ‘void
». Также должна быть возможность построить переменнуюT
без аргумента; то есть он должен иметь доступный (неявный или явный) конструктор по умолчанию, если он относится к типу класса.- Выражения ожидания могут не появляться в теле обработчика исключений и не должны выполняться, пока исполняющая нить удерживает блокировку любого вида.
За этими ограничениями должна быть причина, и из-за недостатка знаний о параллелизме я не могу понять, каковы причины. Может ли кто-нибудь рассказать мне об этой теме?
Это ограничение относится к вариационным функциям в стиле C или шаблонным вариативным функциям C ++ 11?
va_*
макросы?В обоих случаях я думал, что компилятор может быть достаточно умен, чтобы определить, какую функцию использовать.
Я понимаю причину возврата std::future
или же std::shared_future
, но я предполагаю, что причина ограничения используемых типов связана с типами, которые могут использовать фьючерсы.
Таким образом, в статье предлагается расширить язык двумя новыми ключевыми словами (resumable и await), которые обеспечивают поведение возобновляемых функций, но, в конце концов, он доверяет существующим конструкциям передавать возвращаемые значения возобновляемых функций между функцией и вызывающей стороной.
Почему бы не предложить какое-то расширение языка для возвращаемых значений? это может (возможно) снять ограничение по умолчанию для конструируемых и копируемых / подвижных типов и исправить асимметрию между возвращаемым типом и возвращаемым типом:
Таким образом, следует отметить, что существует асимметрия между наблюдаемым поведением функции извне (вызывающей стороной) и изнутри: внешняя перспектива состоит в том, что функция возвращает значение типа
future<T>
в первой точке приостановки, в то время как внутренняя перспектива состоит в том, что функция возвращает значение типаT
с помощью оператора возврата (…)
Полагаю, что ожидать чего-то при обнаружении исключения не имеет смысла, но я понятия не имею об ограничении заблокированных потоков.
Я почти уверен, что все эти ограничения связаны с тем, что контекст возобновляемой функции должен быть «сохранен» и «возобновлен» — я ожидаю, что механизм создаст временную «копию стека» или что-то подобное. Так:
Переменное количество аргументов
Это действительно означает, что вещи используют va_arg
функциональность — не потому, что задействованы макросы, а потому, что внешнему агенту невозможно узнать количество фактических аргументов — для printf
, вам нужно прочитать строку формата, для некоторых других последний отмечен NULL
, Так сколько контекста нужно сохранить?
Закрытые темы
Итак, мы только что сказали «мы не хотим, чтобы этот поток прерывался», а затем мы идем и говорим: «Теперь давайте запустим что-то еще». Это все равно что сказать: «Пожалуйста, ни при каких обстоятельствах меня не будут прерывать, пока я принимаю ванну», когда я захожу в ванну, и в то же время говорю: «Можете ли вы позвонить мне через 2 минуты …» — при условии, что ванна занимает больше 2 минут, одно из них будет неверным.
Конструктор по умолчанию
Я вполне уверен, что логика здесь в том, что это сделало бы всю концепцию достаточно сложной, если бы возвращаемое значение, которое должно быть сконструировано, должно было передавать аргументы конструктору. Как бы вы описали такую вещь? И вам также придется «держаться» за эти аргументы, находясь в состоянии ожидания. Опять же, делая сохранение контекста более сложным.