使用 std::future 从函数返回多个值
Returning multiple values from a function with std::future
根据 this Q&A,如果函数 return 是一个值,std::future
可以工作,但您不能传递引用并获取多个值。所以像这样的函数将不会给出 std::future
:
的结果
void doSomething(int &a, int &b) { a = 1; b = 2; }
我的想法是创建一个结构并具有函数 return 结构:
#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
中获取两个或更多值? 还有比这更好的方法吗?
您得到的错误与您的实现无关,这是默认情况下 linker 不 link 使用 pthread
库。
将 flagg -pthread
添加到编译器和 linker(如果您使用的是 GCC 或 Clang),它应该可以工作。
或者,将 pthread
库添加为带有 -l
linker 标志的 linker 库。
but you can't pass references and get multiple values.
不正确,如链接问题的答案中所述,您 可以 传递引用,您只需要使用 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);
但是那个函数没有return多个值,它使用out参数来设置多个变量。对于 return 多个值的函数,您确实需要 return 一些复合类型,例如结构,但这与 std::future
无关,这就是 C++ 的工作原理。函数只有一个 return 类型。
你的解决方案 returning 一个结构是惯用的方式,尽管你的代码会在 运行 时失败,因为你使用了 t1.get()
两次,而且你只能检索结果来自 std::future
一次。要两次访问结果,请将结果移动到新变量中:
auto result = t1.get();
或将 future 转换为 std::shared_future
,从而允许多次访问结果:
auto t2 = t1.share();
但是您不需要使用自定义结构来 return 多个值,您可以只使用 pair
或 tuple
:
#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));
}
根据 this Q&A,如果函数 return 是一个值,std::future
可以工作,但您不能传递引用并获取多个值。所以像这样的函数将不会给出 std::future
:
void doSomething(int &a, int &b) { a = 1; b = 2; }
我的想法是创建一个结构并具有函数 return 结构:
#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
中获取两个或更多值? 还有比这更好的方法吗?
您得到的错误与您的实现无关,这是默认情况下 linker 不 link 使用 pthread
库。
将 flagg -pthread
添加到编译器和 linker(如果您使用的是 GCC 或 Clang),它应该可以工作。
或者,将 pthread
库添加为带有 -l
linker 标志的 linker 库。
but you can't pass references and get multiple values.
不正确,如链接问题的答案中所述,您 可以 传递引用,您只需要使用 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);
但是那个函数没有return多个值,它使用out参数来设置多个变量。对于 return 多个值的函数,您确实需要 return 一些复合类型,例如结构,但这与 std::future
无关,这就是 C++ 的工作原理。函数只有一个 return 类型。
你的解决方案 returning 一个结构是惯用的方式,尽管你的代码会在 运行 时失败,因为你使用了 t1.get()
两次,而且你只能检索结果来自 std::future
一次。要两次访问结果,请将结果移动到新变量中:
auto result = t1.get();
或将 future 转换为 std::shared_future
,从而允许多次访问结果:
auto t2 = t1.share();
但是您不需要使用自定义结构来 return 多个值,您可以只使用 pair
或 tuple
:
#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));
}