6
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在不设置值的情况下销毁它是行不通的。

4

2 回答 2

5

有没有办法在调用 get 之前检查未来是否会抛出?

不,因为这在某种程度上等于接收未来存储的值。

我希望valid会检查......我不太确定如何让valid返回false。

如果未来引用只能由或创建的共享状态std::async,则 Valid 将返回 true 。一个反例是默认构造的。一旦您调用或在有效(有效==真)未来一次,有效也将是错误的。在无效(有效 == 假)的未来 调用任何其他函数或移动赋值运算符是 UB。std::packaged_taskstd::promisestd::futuregetshare
valid

在不设置值的情况下破坏承诺是不行的。

不,如上所述,这不是有效的点,因为未来仍然指的是共享状态,只是另一方 - 承诺 - 没有实现。如果在销毁 Promise 时没有设置任何值或异常,则会设置一个异常来指示已损坏的 Promise。

于 2013-03-18T00:15:19.993 回答
1

有没有办法在调用 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状态具有结果,该结果可以是值,也可以是异常。两者都是有效的结果。如果您不想处理异常,则应首先确保未在共享状态下设置异常。

于 2013-03-18T11:27:08.197 回答