The return type of std::async is std::future<V>, where V is: ... The call to std::async synchronizes with the call to f, and the completion of f is sequenced before making the shared state ready.

If the future is the result of a call to std::async that used lazy evaluation, this function returns immediately without waiting. This function may block for longer than timeout_duration due to scheduling or resource contention delays. The standard recommends that a steady clock is used to measure the duration.

Checks if the future refers to a shared state. This is the case only for futures that were not default-constructed or moved from (i.e. returned by std::promise::get_future (), std::packaged_task::get_future () or std::async ()) until the first time get () or share () is called. The behavior is undefined if any member function other than the destructor, the move-assignment operator, or valid is ...

namespace std { template<class R> class shared_future { public: shared_future() noexcept; shared_future(const shared_future& rhs) noexcept; shared_future(future<R>&&) noexcept; shared_future(shared_future&& rhs) noexcept; ~shared_future(); shared_future& operator=(const shared_future& rhs) noexcept; shared_future& operator=(shared_future&& rhs ...

In summary: std::future is an object used in multithreaded programming to receive data or an exception from a different thread; it is one end of a single-use, one-way communication channel between two threads, std::promise object being the other end.