期货,承诺和例外
std::promise<int> p1;
auto f = p1.get_future();
{
std::promise<int> p2(std::move(pr));
}
bool valid = f.valid(); // true
f.wait(); // does not throw, or fail, but returns immediately
f.get(); // throws an exception
有没有什么办法可以在致电get
之前检查未来是否会抛出?我希望valid
会检查...我真的不知道如何让valid
返回false。销毁promise
而不设置值不会执行此操作。期货,承诺和例外
有没有什么办法可以在拨打 之前检查未来是否会抛出?
不,因为这在某种程度上等于接收未来存储的值。
我希望有效的检查...我不太确定如何得到有效的 返回false。如果未来是指可以仅通过
std::async
,std::packaged_task
或std::promise
创建一个共享状态
有效将返回true。一个反例是默认构造的std::future
。一旦您在有效(有效==真实)未来一次呼叫get
或share
,有效值也将为假。
调用除valid
之外的任何其他函数或移动赋值运算符对无效(有效==虚假)将来都是UB。
销毁承诺而未设置值不会执行此操作。
不,如上所述不是有效的点,因为未来仍然指的是共享状态只是另一方 - 承诺 - 没有实现。如果破坏承诺,则不设置任何值或例外,则会设置一个例外来指示已破坏的承诺。
有什么办法可以在调用get之前检查未来是否会抛出?
你的问题等同于:
有没有什么办法来检查,如果功能会调用它之前扔?
这两个问题的答案总的来说不是。
考虑:
int func_that_might_throw()
{
if (rand() % 2)
throw 1;
return 0;
}
std::future<int> f = std::async(&func_that_might_throw);
int result = f.get();
的async
调用可以返回一个延迟功能,在这种情况下,功能甚至不运行,直到您叫get()
,所以一般是没有办法事先知道是否结果将是一个值或一个例外。 (您可以通过调用f.wait_for(std::chrono::seconds(0))
来检测延迟的函数,但async
可能不会返回延迟函数,并且在这种情况下,当您尝试检查它是否存储异常时,该函数仍可能异步运行,因此您必须检查如果它已准备好并且存在异常,那么检查就会变得非常混乱。)
一个有效的future
具有已准备就绪的共享状态,其结果可能是值或异常。两者都是有效的结果。如果你不想处理异常,那么你应该确保首先不会在共享状态中设置异常。
未来::得到并不一定有像'if(IsReady())返回值;否则如果(!PromiseExists())抛出:promise;'?因此可能有一个函数返回'!IsReady()&&!PromiseExists()'。我不明白为什么这种情况不适合无效(...'valid()== false),但设计师没有这样做。 – David 2013-03-18 14:17:58
简要说一下我的用例:我在每一帧(〜20)中启动了一堆异步任务(使用我自己的异步队列,而不是std :: async)。下一帧我想取消任何尚未执行的任务,并推送一组20个可能执行的任务。我希望我的异步队列在我将工作推向未来时给我一个未来,但如果我不能通过使用未来告诉工作已经取消或不能使用期货,或者我必须包裹它们。我可以通过调用get和捕获异常来实现,但这太慢了。 – David 2013-03-18 14:22:46
给你的第一个评论:当诺言消失时,'broken_promise'被设置,而不是当你寻找结果。 'valid()'意味着“共享状态”,未来仍然有一个共享状态,就像现在已经多次声明的那样。 – 2013-03-18 17:11:21
'std :: future'可以被看作是std :: promise'状态的观察者。如果诺言消失了,未来就是悬崖勒马。这不是UB,因为sehe说,但你得到一个'std :: broken_promise'异常,因为承诺永远不能满足。 – Xeo 2013-03-17 23:47:10
一旦您调用'get'或'share'一次,valid将返回false。 – inf 2013-03-17 23:57:11
[future :: valid](http://en.cppreference.com/w/cpp/thread/future/valid)表示“检查未来是否指向共享状态”。如果承诺没有了,价值从未设置,那不是说没有共享状态吗? – David 2013-03-17 23:57:27