从具有std :: future的函数返回多个值

时间:2015-02-12 09:24:56

标签: multithreading c++11 future

根据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获取两个或更多值? 有比这更好的方法吗?

2 个答案:

答案 0 :(得分:4)

  

但您无法传递引用并获得多个值。

不正确,正如链接问题的答案中所解释的,您可以传递引用,您只需使用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);

但是该函数没有返回多个值,它使用out参数来设置多个变量。对于返回多个值的函数,您需要返回一些复合类型,例如struct,但这与std::future无关,这与C ++的工作方式有关。函数只有一个返回类型。

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

auto result = t1.get();

或将未来转换为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));
}

答案 1 :(得分:1)

您得到的错误与您的实现无关,默认情况下链接器不会与pthread库链接。

将flagg -pthread添加到编译器和链接器(如果您正在使用GCC或Clang),它应该可以工作。

或者,将pthread库添加为带有-l链接器标志的链接库。