Std:: packaged_task не нарушает promises при уничтожении?
Я сталкиваюсь с чем-то очень странным при использовании пакетных задач. При чтении ~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 или что-то пропустил?
Ответы
Ответ 1
Вы правы. ~packaged_task()
отказывается от общего состояния (§30.6.9.1 [futures.task.members]/p9), что означает, что если общее состояние не готово, сохраняется объект исключения типа future_error
с условием ошибки broken_promise
, затем сделать общее состояние готовым; и затем освобождение общего состояния (§30.6.4 [futures.state]/p7).
Это известная ошибка, которая будет в следующей версии Visual Studio, которая, скорее всего, выйдет через некоторое время в 2015 году. Она также исправлена в CTP, но это довольно плохая идея использовать это для производственного кода...
Ответ 2
Я думаю, что это ошибка, стандарт говорит, что ~packaged_task
отказывается от общего состояния, а это значит, что если он еще не готов, он должен сохранить исключение broken_promise
и сделать состояние готовым, как и ожидалось.
Полное раскрытие: ваш тест ideone.com использует GCC, и я реализовал GCC <future>
, поэтому я мог бы быть предвзятым, когда я говорю, что его поведение правильное... но я думаю, что он по-прежнему верен; -)