根据this Q&A的说法,std::future在函数返回值的情况下有效,但是您不能传递引用并获取多个值。所以像这样的函数将不会给std::future提供任何结果:
void doSomething(int &a, int &b) { a = 1; b = 2; }
我的想法是创建一个结构并使该函数返回该结构:

#include <iostream>
#include <future>
using namespace std;

struct myData
{
    int a;
    int b;
};

myData doSomething()
{
  myData d;
  d.a = 1;
  d.b = 2;
  return d;
}

int main()
{
    future<myData> t1 = async(launch::deferred, doSomething);

    printf("A=%d, B=%d\n", t1.get().a, t1.get().b);

    return 0;
}

因此,如何从std::future获取两个或多个值? 是否有比这更好的方法?

最佳答案



并非如此,正如链接问题的答案中所述,您可以传递引用,您只需要使用std::ref即可保护它们免于腐烂。因此,要调用void doSomething(int &a, int &b),您将使用:

int a;
int b;
auto fut = std::async(std::launch::deferred, doSomething, std::ref(a), std::ref(b));
fut.get();  // wait for future to be ready
std::printf("A=%d, B=%d\n", a, b);

但是该函数不会返回多个值,它使用了参数来设置多个变量。对于要返回多个值的函数,您确实需要返回某种复合类型(例如struct),但这与std::future无关,这就是C++的工作方式。函数具有单个返回类型。

返回结构的解决方案是惯用的方式,尽管您的代码将在运行时失败,因为您两次使用了t1.get(),并且只能从std::future中检索一次结果。要两次访问结果,请将结果移到新变量中:
auto result = t1.get();

或将future转换为std::shared_future,以允许多次访问结果:
auto t2 = t1.share();

但是您不需要使用自定义结构来返回多个值,只需使用pairtuple即可:
#include <cstdio>
#include <future>
#include <tuple>

std::tuple<int, int> doSomething()
{
  return std::make_tuple(1, 2);
}

int main()
{
    auto fut = std::async(std::launch::deferred, doSomething);
    auto result = fut.get();
    std::printf("A=%d, B=%d\n", std::get<0>(result), std::get<1>(result));
}

关于multithreading - 从带有std::future的函数返回多个值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28473695/

10-11 23:01
查看更多