延迟的未来(仅通过使用std::async
标志调用std::launch::deferred
来实现)的思想是,只有当有人试图等待或试图提取未来的未来主义值或异常时,才会调用回调。到那时,回调还没有执行。
如果我将一个延后的未来附加到std::future::then
中,会发生什么?延迟的未来将丢失(then
使未来无效),并返回一个新的未来。
在这种情况下,按照标准,应该发生什么?新的未来也是一个被推迟的未来吗?会不会只是陷入僵局?这个问题在最近的文件中没有提到。
发布于 2018-08-29 18:00:58
在我看来,这似乎是TS中的一个bug。或者至少有一个文件不足的陷阱。
以下是TS的文本:
2.3未来.独特的未来.6-10
模板见下文(F& func); 要求: 调用(DECAY_COPY (std::forward(func))、std::move(*this))应该是一个有效的表达式。 效果: 该函数创建一个与返回的未来对象关联的共享状态。另外, 当对象的共享状态准备就绪时,将在未指定的执行线程上调用延续
INVOKE(DECAY_COPY(std::forward<F>(func)), std::move(*this))
,然后在调用的线程中计算对DECAY_COPY()
的调用。 从延续返回的任何值都存储在结果的未来的共享状态中。从连续执行中传播的任何异常都存储为结果未来的共享状态的异常结果。 返回: 当result_of_t<decay_t<F>(future<R>)>
为future<R2>
时,对于某些类型的R2,该函数返回future<R2>
。否则,函数返回future<result_of_t<decay_t<F>(future<R>)>>
。[注:上述规则称为隐式展开。如果没有这条规则,那么接受可调用的返回future<R>
的返回类型将是future<future<R>>
。此规则避免了这种嵌套的未来对象。下面的f2
类型是future<int>
,而不是future<future<int>>
: [例子: 未来f1 = g();未来f2 =f1.然后(future f{future f{ f3 = h();返回f3;}); -最终例子] -尾注] 邮政条件:valid() == false
关于最初的未来。从那时起,valid() == true
又回到了未来。注:在隐式展开的情况下,在延续完成后,才能确定从那功能返回的未来的有效性。如果它无效,则生成的未来就会就绪,只有std::future_error
类型例外,错误条件为std::future_errc::broken_promise
。-尾注
推迟以后的任务没有特例。如果该延迟的未来任务在调用.then
之前还没有准备好,那么就没有办法使其就绪,因此无法调用已损坏的func
副本。
shared_future
的文本类似;在那里,您仍然可以在调用.then
之后使shared_future
做好准备。
如果这是有意的,那么在一个没有准备好的、延迟的、唯一的未来上的.then
将导致一个永远无法准备好的future
的返回值--这在TS/标准中应该是明确的。如果不打算这样做,则需要更改标准文本。
请注意,这些更改不会出现在2018年发布的N4762标准草案中。
我不确定标准应该如何解决这个问题;.then
语义对于shared_future
来说是合理的,但对于future
则不合理,不同的语义将是令人惊讶的。
https://stackoverflow.com/questions/51454704
复制相似问题