Я сталкиваюсь с чем-то очень странным при использовании пакетных задач. При чтении ~ packaged_task У меня складывается впечатление, что если std::packaged_task
уничтожается до его выполнения, обещание будет нарушено, и попытка получить результат из будущего должна привести к std::future_error
,
Однако в Visual Studio 2013 этого не происходит. Возьмите следующий код:
#include <iostream>
#include <future>
#include <functional>
int main() {
std::future<int> f;
{
std::packaged_task<int()> task([](){return 3; });
f = task.get_future();
}
std::cout<<f.get()<<std::endl;
return 0;
}
Я ожидаю получить std::future_error
на f.get()
но вместо этого он блокируется, ожидая выполнения упакованной задачи.
Попробуем другой компилятор: http://ideone.com/Wt0WOc действительно бросает std::future_error("Broken promise")
…
Я вижу ошибку в Visual Studio 2013 или я что-то пропустил?
Ты прав. ~packaged_task()
отказывается от общего состояния (§30.6.9.1 [futures.task.members] / p9), что означает, что если общее состояние не готово, сохраняется объект исключения типа future_error
с ошибочным состоянием broken_promise
затем готовит общее состояние; и затем освобождение общего состояния (§30.6.4 [futures.state] / p7).
Это известная ошибка тот будет исправлено в следующей версии Visual Studio, которая, вероятно, выйдет где-то в 2015 году. Это также исправлено в CTP, но довольно плохо использовать это для производственного кода …
Я думаю, что это ошибка, стандарт говорит ~packaged_task
отказывается от общего состояния, что означает, что если он еще не готов, он должен сохранить broken_promise
исключение и подготовить государство, как вы ожидаете.
Полное раскрытие: ваш тест ideone.com использует GCC, и я реализовал GCC <future>
поэтому я могу быть предвзятым, когда скажу, что его поведение правильное … но я думаю, что оно по-прежнему правильно 😉