In this chapter's section The future of futures, we introduced std::async, which is a simple wrapper around a thread constructor with the result captured into a std::future. Its implementation looks more or less like this:
template<class F>
auto async(F&& func) {
using ResultType = std::invoke_result_t<std::decay_t<F>>;
using PromiseType = std::promise<ResultType>;
using FutureType = std::future<ResultType>;
PromiseType promise;
FutureType future = promise.get_future();
auto t = std::thread([
func = std::forward<F>(func),
promise = std::move(promise)
]() mutable {
try {
ResultType result = func();
promise.set_value(result);
} catch (...) {
promise.set_exception(std::current_exception());
}
...