std::future in C++
The C++ Concurrency support library includes the std::future class template, which has been available since C++11. This template is defined in the <future> header and provides a means to access the outcomes of asynchronous operations.
What is std::future in C++?
In C++, the std::future is a class template used to receive the result of an asynchronously executed task that is not computed yet i.e. future value. Asynchronous operations in C++ are managed using std::async, std::packaged_task, or std::promise, which returns a std::future object. We can use this std::future object to verify, await, or obtain the outcome of the operation.
It is to be noted that we can receive the result of the computation only once in the program as the state of the future is reset after getting the result.
Syntax of std::future
The syntax to define a std::future object is pretty straightforward:
std::future<type> name;
where,
- name: name of the future object.
- type: type of the data that is to be recieved.
Member Functions in std::future Class
The std::future class consists of the various member functions providing basic functionality. Some of the common ones are:
S. No. |
Function |
Description |
---|---|---|
1 |
get() | Function to get the value received. |
2 |
wait() | This function tells the compiler to wait() for the process to be done. |
3 |
wait_for() | This function tells the compiler to wait() for the specified time duration for the process to be finished. |
4 |
wait_until() | This function tells the compiler to wait() till the specified time duration for the process to be finished. |
5 |
valid() | This function checks if the future() object has a shared state i.e. is it valid to perform get() operation. |
Examples of std::future in C++
Example 1: Using std::future to Print the Value Returned by Asynchronous Task
C++
// C++ Program to illustrate the use of std::future #include <chrono> #include <future> #include <iostream> using namespace std; // A simple function that returns some integer value int returnTwo() { return 2; } // driver code int main() { // creating a future object and a thread that executes // the function return two asynchronously future< int > f = async(launch::async, returnTwo); // getting and printing the result cout << f.get(); return 0; } |
Output
2
Example 2: Trying to Get the Value Multiple Times from std::future
C++
// C++ Program to illustrate the use of std::future #include <chrono> #include <future> #include <iostream> using namespace std; // A simple function that returns some integer value int returnTwo() { return 2; } // driver code int main() { // creating a future object and a thread that executes // the function return two asynchronously future< int > f = async(launch::async, returnTwo); // getting and printing the result cout << f.get(); // trying for second time cout << f.get(); return 0; } |
Output
terminate called after throwing an instance of 'std::future_error' what(): std::future_error: No associated state
The solution to the above problem is to use the future::valid() function to check the state of the future object before using get() method.
Example 3: Avoid the No Associate State Error using valid()
C++
// C++ Program to illustrate the use of std::future #include <chrono> #include <future> #include <iostream> using namespace std; // A simple function that returns some integer value int returnTwo() { return 2; } // driver code int main() { // creating a future object and a thread that executes // the function return two asynchronously future< int > f = async(launch::async, returnTwo); // getting and printing the result if (f.valid()) { cout << f.get() << endl; } else { cout << "Invalid State, Please create another Task" << endl; } // trying for second time if (f.valid()) { cout << f.get() << endl; } else { cout << "Invalid State, Please create another Task" << endl; } return 0; } |
Output
2 Invalid State, Please create another Task
Apart from the async() method, we can also get future objects using std::packaged_task() and std::promise(). The below example demonstrates the use of std::future with std::promise.
Example 4: Using std::future with std::promise
C++
// C++ Program to illustrate the use of std::future #include <chrono> #include <future> #include <iostream> using namespace std; // A simple function that returns some integer value void foo(promise< int > p) { p.set_value(25); } // driver code int main() { // creating a future object and a thread that executes // the function return two asynchronously promise< int > p; future< int > f = p.get_future(); ; // moving the task thread t(foo, move(p)); t.join(); cout << f.get(); return 0; } |
Output
25
Conclusion
The std::future provides the programmers with the method for thread communication in asynchronous programming in C++ in an easy way. It is especially helpful in cases where we need to do some tasks in the background and need the result of that task in the main process.