-1

I am working with std::async and std::future in c++, but am having a bit of trouble. When I run this code, i expect to see (in the stdout) "hello world" but, instead I get nothing:

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

struct A {
  future<string>* test;
};

string getStr() {
  return "hello world";
}

A callA() {

  future<string> a = async(&getStr);

  return A{ &a };
}

int main() {
  A a = callA();
  cout << a.test->get() << endl;
}

I am using a pointer to a future because in my real program, i have another struct in place of the std::string:

struct A;
struct B;

typedef struct A {
  future<B>* b;
} A;

typedef struct B {
  A a;
} B;

and even if i don't use a pointer it will give me this error:

error: use of deleted function 'std::future<_Res>::future(const std::future<_Res>&) [with _Res = std::__cxx11::basic_string<char>]'

(For the above error, i know that i can use std::move to fix it as seen here, but i need to use the pointer)

So how can i actually get the output of "hello world" from this program?

Ank i zle
  • 2,089
  • 3
  • 14
  • 36

2 Answers2

2

you use a pointer to a temporary object. the temporary object is destroyed at the exit of the function. so you can move your future object to your struct:

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

struct A {
  future<string> test;
};

string getStr() {
  return "hello world";
}

A callA() {

  future<string> a = async(&getStr);

  return A{ std::move(a) };
}

int main() {
  A a = callA();
  cout << a.test.get() << endl;
}

if for some reason you have to use a pointer - then you should prolong the lifetime of your future. (e.g. add the future to a container and later remove from it after the usage of the future)

Alexander
  • 698
  • 6
  • 14
2

The future is destroyed as soon as callA() returns, so you have a pointer to an object that no longer exists. a.test->get() is therefore undefined behavior, and anything might happen -- including indefinitely blocking, or crashing, or actually printing the right result.

If you wish to return it from the function as a pointer, then use std::unique_ptr:

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

struct A {
  unique_ptr<future<string>> test;
};

string getStr() {
  return "hello world";
}

A callA() {
  future<string> a = async(&getStr);

  return A{ make_unique<future<string>>(std::move(a)) };
}

int main() {
  A a = callA();
  cout << a.test->get() << endl;
}

(Demo)

Side note: using namespace std; is a bad practice. Don't do it.

cdhowie
  • 158,093
  • 24
  • 286
  • 300