std::future::get(3)
π std::future::get(3) π
okay so bestie, we're in the C++ Standard Libary man pages and today's main character is std::future::get β yes that get, the one everyone's been waiting for (literally, she waits). pull up a chair π«Ά
β¨ SYNOPSIS β¨
here's the whole cast, three overloads, all of them iconic since C++11:
Main template
T get(); (1) (since C++11)
std::future<T&> specializations
T& get(); (2) (since C++11)
std::future<void> specialization
void get(); (3) (since C++11)
πΈ DESCRIPTION πΈ
so the get member function waits (like, by actually calling wait(), no shortcuts) until the shared state is ready, and then retrieves the value stored in the shared state (if there even is one, iykyk). and the second you call this function? valid() is false. gone. done. that's her arc π
β οΈ ifvalid()isfalsebefore the call to this function, the behavior is undefined. no cap, undefined. do not do this.
π RETURN VALUE π
- 1) the value
vstored in the shared state, asstd::move(v). slay, moved. - 2) the reference stored as value in the shared state.
- 3) (none) β yeah she gives you nothing and honestly that's fine π
π₯ EXCEPTIONS π₯
if an exception was stored in the shared state referenced by the future (like, say, via a call to std::promise::set_exception()) then that exception will be thrown. so get() can absolutely jump scare you. be ready. π
β NOTES β
the C++ standard recommends that implementations detect the case when valid() is false before the call and throw a std::future_error with an error condition of std::future_errc::no_state. so they're encouraged to catch you being chaotic, but it's a recommendation, not a promise. π
π¦ EXAMPLE π¦
// Run this code
#include <chrono>
#include <future>
#include <iostream>
#include <string>
#include <thread>
std::string time()
{
static auto start = std::chrono::steady_clock::now();
std::chrono::duration<double> d = std::chrono::steady_clock::now() - start;
return "[" + std::to_string(d.count()) + "s]";
}
int main()
{
using namespace std::chrono_literals;
{
std::cout << time() << " launching thread\n";
std::future<int> f = std::async(std::launch::async, []
{
std::this_thread::sleep_for(1s);
return 7;
});
std::cout << time() << " waiting for the future, f.valid() = "
<< f.valid() << '\n';
int n = f.get();
std::cout << time() << " f.get() returned " << n << ", f.valid() = "
<< f.valid() << '\n';
}
{
std::cout << time() << " launching thread\n";
std::future<int> f = std::async(std::launch::async, []
{
std::this_thread::sleep_for(1s);
return true ? throw std::runtime_error("7") : 7;
});
std::cout << time() << " waiting for the future, f.valid() = "
<< f.valid() << '\n';
try
{
int n = f.get();
std::cout << time() << " f.get() returned " << n
<< ", f.valid() = " << f.valid() << '\n';
}
catch (const std::exception& e)
{
std::cout << time() << " caught exception " << e.what()
<< ", f.valid() = " << f.valid() << '\n';
}
}
}
Possible output:
[0.000004s] launching thread
[0.000461s] waiting for the future, f.valid() = 1
[1.001156s] f.get() returned with 7, f.valid() = 0
[1.001192s] launching thread
[1.001275s] waiting for the future, f.valid() = 1
[2.002356s] caught exception 7, f.valid() = 0
π DEFECT REPORTS π
so the following behavior-changing defect reports got applied retroactively to previously published C++ standards (yes, time travel, we love to see it β):
LWG 2096β applied to C++11: behavior as published was that overload (1) needed to check whetherTisMoveAssignable; correct behavior is that it's not required.
π SEE ALSO π
validβ checks if the future has a shared state (public member function) π
alright bestie that's the whole page, go forth and get() responsibly πβ¨π
π§ source + version + date, as promised: straight fromhttp://cppreference.com, the 2024.06.10 drop of the C++ Standard Libary pages β pagestd::future::get(3), mwah π
π¦ where this page comes from
- nixpkgs unstable: stdman 2024.07.05
- opensuse-leap 16.0: stdman 2024.07.05-bp160.1.9 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms