but you can't pass references and get multiple values.
Not true, as explained in the answers to the linked question, you can pass references, you just need to use std::ref
to protect them from decaying. So to call void doSomething(int &a, int &b)
you would use:
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);
But that function doesn't return multiple values, it uses out parameters to set multiple variables. For a function to return multiple values you do need to return some composite type such as a struct, but that has nothing to do with std::future
, that's how C++ works. Functions have a single return type.
Your solution returning a struct is the idiomatic way, although your code will fail at run-time because you use t1.get()
twice, and you can only retrieve the result from a std::future
once. To access the result twice either move the result into a new variable:
auto result = t1.get();
or convert the future to a std::shared_future
which allows the result to be accessed multiple times:
auto t2 = t1.share();
But you don't need to use a custom structure to return multiple values, you can just use a pair
or 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));
}