简体   繁体   English

有没有办法在std :: experimental :: future中使用std :: async?

[英]Is there a way to use std::async with std::experimental::future?

Note: Below is illegal even in C++17! 注意:即使在C ++ 17中,以下内容也是非法的!

#include <thread>
#include <future>
#include <experimental/future>

using namespace std;

int step1(experimental::future<int>)
{
    return {};
}

int step2(experimental::future<int>)
{
    return {};
}

int step3(experimental::future<int>)
{
    return {};
}

int main()
{
    return async([](){ return {}; })
        .then(step1)
        .then(step2)
        .then(step3)
        .get();
}

C++1z provides two types of future : C ++ 1z提供了两种类型的future

  1. std::future
  2. std:experimental::future

However, std::async returns std::future only, so the code above is illegal. 但是, std::async仅返回std::future ,因此上面的代码是非法的。 If std::async returns std:experimental::future , then it would be ok. 如果std::async返回std:experimental::future ,那就没关系。

My question is: 我的问题是:

Is there a way to use std::async with std::experimental::future that makes the code above legal under C++1z? 有没有办法在std::experimental::future中使用std::async ,使得代码在C ++ 1z下面合法?

Is there a way to use std::async with std::experimental::future that makes the code above legal under C++1z? 有没有办法在std::experimental::future中使用std::async ,使得代码在C ++ 1z下面合法?

Nope. 不。 std::async returns a std::future<T> which, despite the name, is an entirely unrelated type to std::experimental::future<T> . std::async返回一个std::future<T> ,尽管名称是std::experimental::future<T> ,但它是一个完全不相关的类型。

You would have to write your own version of async that gives you the new kind of future . 您必须编写自己的async版本,为您提供新的future A simplified version would be something like: 简化版本将是这样的:

template <class F, class... Args,
    class R = std::invoke_result_t<std::decay_t<F>, std::decay_t<Args>...>>
std::experimental::future<R> new_async(F&& f, Args&&... args)
{
    std::experimental::promise<R> p;
    auto fut = p.get_future();

    std::thread thread([p=std::move(p), f=std::forward<F>(f),
        args=std::tuple<std::decay_t<Args>...>(std::forward<Args>(args)...)] () mutable
    {
        try 
        {
            if constexpr(std::is_void_v<R>)
            {
                std::apply(std::move(f), std::move(args));
                p.set_value();
            }
            else 
            {
                p.set_value(std::apply(std::move(f), std::move(args)));
            }
        }
        catch(...)
        {
            p.set_exception(std::current_exception());
        }
    });

    thread.detach();
    return fut;
}

That doesn't support other launch policies like async does, but it's just a start. 这不支持像async这样的其他启动策略,但它只是一个开始。

It seems like std::experimental::future has the same constructors as std::future , so it should be possible to construct an std::experimental::future from an std::future . 看起来像 std::experimental::future具有相同的构造为std::future ,所以它应该是可以构建一个std::experimental::futurestd::future However, as pointed out by ildjarn it actually isn't according to the latest draft , so there seems to be no way to do this until the TS changes accordingly. 然而,正如ildjarn指出的那样 ,它实际上并不是根据最新的草案 ,所以在TS相应改变之前似乎没有办法做到这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM