15

我在使用打包任务时遇到了一些非常奇怪的事情。在阅读~packaged_task时,我得到的印象是,如果 astd::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_erroronf.get()但它反而阻塞,等待打包的任务被执行。

尝试另一个编译器:http: //ideone.com/Wt0WOc确实会抛出一个std::future_error("Broken promise")......

我是在 Visual Studio 2013 中看到错误还是我错过了什么?

4

2 回答 2

10

你是对的。~packaged_task()放弃共享状态(§30.6.9.1 [futures.task.members]/p9),这意味着,如果共享状态未准备好,则存储一个future_error错误条件为的类型的异常对象broken_promise,然后使共享状态准备好;然后释放共享状态(§30.6.4 [futures.state]/p7)。

这是一个已知的错误在下一版本的 Visual Studio 中修复,可能会在 2015 年的某个时间发布。它也在 CTP 中修复,但将其用于生产代码是一个非常糟糕的主意......

于 2014-09-10T10:40:23.060 回答
7

我认为这是一个错误,标准说~packaged_task放弃共享状态,这意味着如果它还没有准备好,它应该存储一个broken_promise异常并使状态准备好,正如你所期望的那样。

全面披露:您的 ideone.com 测试使用 GCC,我实施了 GCC <future>,所以当我说它的行为正确时我可能会有偏见……但我认为它仍然是正确的 ;-)

于 2014-09-10T10:19:15.117 回答