期货,承诺和例外

时间:2013-03-17 23:35:26

标签: c++ asynchronous c++11

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不会这样做。

2 个答案:

答案 0 :(得分:5)

  

在打电话之前,有没有办法检查未来是否会抛出   获得?

不,因为这将等于接收将来存储的值。

  

我希望有效会检查......我不确定如何有效   返回false。

如果将来引用只能由std::asyncstd::packaged_taskstd::promise创建的共享状态,则有效将返回true。反例将是默认构造的std::future。一旦您在有效(有效== true)的未来调用getshare一次,有效也将为false。
在无效(有效== false)的未来调用除valid之外的任何其他函数或移动赋值运算符是UB。

  

在不设置值的情况下销毁承诺不会这样做。

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

答案 1 :(得分: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具有结果,该结果是值或异常。两者都是有效的结果。如果您不想处理异常,那么您应该确保首先没有在共享状态中设置异常。