поведение std :: async (std :: launch :: deferred) + std :: future :: then

Идея отсроченного будущего (достигается только путем вызова std::async с std::launch::deferred флаг) заключается в том, что обратный вызов вызывается только тогда, когда кто-то пытается подождать или извлечь футуристическое значение или исключение из будущего. к тому времени обратный вызов не выполняется.

Что произойдет, если я прикреплю продолжение к отложенному будущему с std::future::then? отложенное будущее потеряно (then аннулирует будущее), и вместо него возвращается новое будущее.

В этом случае, согласно стандарту, что должно произойти? новое будущее — это также отложенное будущее? это просто тупик? этот вопрос не рассматривается в последней документации.

21

Решение

Это, на мой взгляд, похоже, ошибка в TS. Или, по крайней мере, недокументированная ловушка.

Вот текст из TS:

template <class F>
see below then(F&& func);

Требуется:

INVOKE(DECAY_COPY (std::forward<F>(func)), std::move(*this)) shall be a valid expression.

Последствия:

Функция создает общее состояние, которое связано с возвращенным будущим объектом. Дополнительно,

Когда общее состояние объекта готово, продолжение INVOKE(DECAY_COPY(std::forward<F>(func)), std::move(*this)) вызывается в неопределенном потоке выполнения с вызовом DECAY_COPY() оценивается в потоке, который вызвал тогда.

Любое значение, возвращаемое из продолжения, сохраняется как результат в общем состоянии результирующего будущего. Любое исключение, переданное из выполнения продолжения, сохраняется как исключительный результат в общем состоянии результирующего будущего.

Возвращает:

когда result_of_t<decay_t<F>(future<R>)> является future<R2>для некоторого типа R2 функция возвращает future<R2>, В противном случае функция возвращает future<result_of_t<decay_t<F>(future<R>)>>, [Примечание: вышеприведенное правило называется неявной разверткой. Без этого правила тип возврата затем принимает вызываемый, возвращающий future<R> был бы future<future<R>>, Это правило избегает таких вложенных будущих объектов. Тип f2 ниже future<int> и не future<future<int>>:

[ Пример:

future<int> f1 = g();
future<int> f2 = f1.then([](future<int> f) {
future<int> f3 = h();
return f3;
});

— конец примера]

— конец примечания]

Постусловия:

valid() == false на оригинальное будущее. valid() == true на будущее вернулся с тех пор. [Примечание: в случае неявного развертывания действительность будущего, возвращенного из thenfunc, не может быть установлена ​​до завершения продолжения. Если он недействителен, получающееся будущее становится готовым, за исключением типа std::future_errorс условием ошибки std::future_errc::broken_promise, — конец примечания]

Для отложенного будущего задания особого случая не существует. Если это отложенное будущее задание не готово перед вызовом .thenнет никакого способа, чтобы это было готово, таким образом, нет никакого способа для разложившейся копии func быть призванным.

Текст для shared_future похож; там вы все равно можете вызвать shared_future быть готовым после звонка .then тем не мение.

Если это предназначено; тот .then в неготовом отложенном уникальном будущем приведет к возвращаемому значению future это никогда не может быть подготовлено — это должно быть явно указано в стандарте TS /. Если это не предназначено, стандартный текст должен быть изменен.

Обратите внимание, что эти изменения не отображаются в Проект стандарта N4762 опубликовано в 2018 году.

Я не уверен, как стандарт должен это исправить; .then семантика разумна для shared_future но не для futureи отличающаяся семантика была бы удивительной.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]