1

在n3721 上写下关于改进std::futureAPI的论文。关于未包装的期货,似乎存在异常传播竞赛。文件说

如果外部 Future 抛出异常,并且在返回的 Future 上调用 .get() ,则返回的 Future 会抛出与外部 Future 相同的异常。之所以如此,是因为内心的未来没有退出

所以我的意思是在以下情况下

#include <iostream>
#include <future>
#include <exception>

using namespace std;

int main() {
    auto prom_one = std::promise<std::future<int>>{};
    auto fut_one = prom_one.get_future();

    std::thread{[prom_one = std::move(prom_one)]() mutable {
        auto prom_two = std::promise<int>{};
        auto fut_two = prom_two.get_future();
        std::thread{[prom_two = std::move(prom_two)]() mutable {
            prom_two.set_exception(std::make_exception_ptr(std::logic_error{}));
        }}.detach();
        prom_one.set_exception(std::make_exception_ptr(std::bad_alloc{}));
    }}.detach();


    auto inner_fut = fut_one.unwrap();
    cout << inner_fut.get() << endl;

    return 0;
}

我之前谈到的比赛是——会抛出哪个异常?内部std::logic_error还是外部std::bad_alloc

我弄错了吗?上面的代码中没有种族吗?

4

1 回答 1

0

我意识到上面的代码没有任何竞争,因为有一个嵌套的未来 -std::future<std::future<int>>只有两种可能性,要么是通过调用设置了内部未来,要么已经设置了std::promise::set_value一个异常并且内部未来没有链接到完全是外部的未来(就像上面的代码一样)。

如果内部未来尚未链接,则外部未来的异常将是抛出的异常。并且如果内部未来已经被链接,则外部未来没有抛出的范围,因为外部未来的承诺已经set_value与内部未来一起调用过一次,因此在外部未来本身上设置异常是无效的(这将导致异常本身被抛出)。

我想这就是报纸所说的

之所以如此,是因为内心的未来没有退出

于 2017-05-12T16:08:29.583 回答