定义于头文件 <future>
template< class T > class future; (1) (C++11 起)
template< class T > class future<T&>; (2) (C++11 起)
template<> class future<void>; (3) (C++11 起)
类模板 std::future
提供访问异步操作结果的机制:
- (通过 std::async 、 std::packaged_task 或 std::promise 创建的)异步操作能提供一个
std::future
对象给该异步操作的创建者。
- 然后,异步操作的创建者能用各种方法查询、等待或从
std::future
提取值。若异步操作仍未提供值,则这些方法可能阻塞。
- 异步操作准备好发送结果给创建者时,它能通过修改链接到创建者的
std::future
的共享状态(例如 std::promise::set_value )进行。
注意, std::future
所引用的共享状态不与另一异步返回对象共享(与 std::shared_future 相反)。
构造函数
future() noexcept; (1) (C++11 起)
future( future&& other ) noexcept; (2) (C++11 起)
future( const future& other ) = delete; (3) (C++11 起)
构造 std::future
对象。
1) 默认构造函数。构造无共享状态的 std::future
。构造后, valid() == false 。
2) 移动构造函数。用移动语义,以 other
的共享状态构造 std::future
。构造后 other.valid() == false 。
3) std::future
不可复制构造 (CopyConstructible) 。
参数
other | - | 获得共享状态来源的另一 std::future |
析构函数
~future(); (C++11 起)
释放任何共享状态。这表示
- 若返回对象或提供方保有到其共享状态的最后引用,则析构共享状态;
- 返回对象或提供方放弃到其共享状态的引用;
移动future对象
future& operator=( future&& other ) noexcept; (1) (C++11 起)
future& operator=( const future& other ) = delete; (2) (C++11 起)
赋值另一 future 对象的内容。
1) 释放任何共享状态并移动赋值 other
的内容给 *this 。赋值后, other.valid() == false 且 this->valid() 将产生与 other.valid() 在赋值前相同的值。
2) std::future 不可复制赋值 (CopyAssignable) 。
参数
other | - | 将转移状态给 *this 的 std::future |
返回值
*this
从 *this 转移共享状态给 shared_future 并返回它
std::shared_future<T> share() noexcept;
转移 *this 的共享状态,若存在,到 std::shared_future 对象。多个 std::shared_future 对象可引用同一共享对象,这对于 std::future 不可能。
在 std::future 上调用 share
后 valid() == false 。
参数
(无)
返回值
含有先前 *this 所保有的共享状态(若存在)的 std::shared_future 对象,如同以 std::shared_future<T>(std:move(*this)) 构造。
检查 future 是否拥有共享状态
bool valid() const noexcept; (C++11 起)
检查期货是否指代共享状态。
这是非默认构造或被移动的期货(例如为 std::promise::get_future() 、 std::packaged_task::get_future() 或 std::async() 所返回)在首次调用 get() 或 share() 前的唯一情况。
若在不指代共享状态的 future
上调用任何析构函数、移动赋值运算符或 valid
以外的成员函数,则行为未定义(尽管鼓励实现在此情况下抛出指示 no_state
的 std::future_error )。从 valid()
为 false
的 future 对象移动是合法的。
参数
(无)
返回值
若 *this 指代共享状态则为 true ,否则为 false 。
等待结果变得可用
void wait() const; (C++11 起)
void wait() const; | (C++11 起) | |
阻塞直至结果变得可用。调用后 valid() == true 。
若调用此函数前 valid()== false 则行为未定义。
参数
(无)
返回值
(无)
异常
(无)
注意
鼓励实现检测调用前 valid == false 的情况并抛出以 std::future_errc::no_state 为 error_condition 的 std::future_error 。
调用示例
#include <iostream>
#include <future>
#include <thread>
int fib(int n)
{
if (n < 3)
{
return 1;
}
else
{
return fib(n - 1) + fib(n - 2);
}
}
int main()
{
std::future<int> f1 = std::async(std::launch::async, []()
{
return fib(20);
});
std::future<int> f2 = std::async(std::launch::async, []()
{
return fib(25);
});
std::cout << "waiting...\n";
f1.wait();
f2.wait();
std::cout << "f1: " << f1.get() << '\n';
std::cout << "f2: " << f2.get() << '\n';
}
输出
等待结果,如果在指定的超时间隔后仍然无法得到结果,则返回。
template< class Rep, class Period >
std::future_status wait_for(
const std::chrono::duration<Rep,Period>& timeout_duration ) const; (C++11 起)
等待结果变得可用。阻塞直至经过指定的 timeout_duration
,或结果变为可用,两者的先到来者。返回值鉴别结果的状态。
此函数可能由于调度或资源争议延迟而阻塞长于 timeout_duration
。
推荐标准库用稳定时钟度量时长。若实现用系统时钟代替,则等待时间可能也对时钟调整敏感。
若调用此函数前 valid()== false 则行为未定义。
参数
timeout_duration | - | 要阻塞的最大时长 |
返回值
常量 | 解释 |
future_status::deferred | 要计算结果的函数仍未启动 |
future_status::ready | 结果就绪 |
future_status::timeout | 已经过时限 |
异常
时钟、时间点或时长在执行中可能抛的任何异常(标准库提供的时钟、时间点和时长决不抛出)。
注意
鼓励实现在调用前检测 valid == false 的情况并抛出以 future_errc::no_state 为 error_condition 的 future_error 。
等待结果,如果在已经到达指定的时间点时仍然无法得到结果,则返回。
template< class Clock, class Duration >
std::future_status wait_until(
const std::chrono::time_point<Clock,Duration>& timeout_time ) const;(C++11 起)
wait_until
等待结果变为可用。它阻塞直至抵达指定的 timeout_time
,或结果变为可用,两者的先到来者。返回值指示 wait_until
为何返回。
若调用此函数前 valid()== false 则行为未定义。
参数
timeout_time | - | 要阻塞到的最大时间点 |
返回值
常量 | 解释 |
future_status::deferred | 要计算结果的函数仍未启动 |
future_status::ready | 结果就绪 |
future_status::timeout | 已经过时限 |
异常
时钟、时间点或时长在执行中可能抛的任何异常(标准库提供的时钟、时间点和时长决不抛出)。
注意
鼓励实现在调用前检测 valid == false 的情况并抛出以 future_errc::no_state 为 error_condition 的 future_error 。
使用倾向 timeout_time
的时钟,不要求是单调时钟。若不连续地调节时钟,则不对此函数的行为保证,但既存实现将 timeout_time
从 Clock
转换到 std::chrono::system_clock ,并委托 POSIX pthread_cond_timedwait 以令等待忠实于系统时钟,但非用户提供 Clock
的调节。任何情况下,由于调度或资源争议延迟,函数可能等待长于抵达 timeout_time
。
调用示例
#include <iostream>
#include <future>
#include <thread>
#include <chrono>
int main()
{
std::chrono::system_clock::time_point two_seconds_passed
= std::chrono::system_clock::now() + std::chrono::seconds(2);
// 做出花 1 秒完成的 future
std::promise<int> p1;
std::future<int> f_completes = p1.get_future();
std::thread([](std::promise<int> p1)
{
std::this_thread::sleep_for(std::chrono::seconds(1));
p1.set_value_at_thread_exit(9);
},
std::move(p1)).detach();
// 做出花 5 秒完成的 future
std::promise<int> p2;
std::future<int> f_times_out = p2.get_future();
std::thread([](std::promise<int> p2)
{
std::this_thread::sleep_for(std::chrono::seconds(5));
p2.set_value_at_thread_exit(8);
},
std::move(p2)).detach();
std::cout << "Waiting for 2 seconds..." << std::endl;
if (std::future_status::ready == f_completes.wait_until(two_seconds_passed))
{
std::cout << "f_completes: " << f_completes.get() << "\n";
}
else
{
std::cout << "f_completes did not complete!\n";
}
if (std::future_status::ready == f_times_out.wait_until(two_seconds_passed))
{
std::cout << "f_times_out: " << f_times_out.get() << "\n";
}
else
{
std::cout << "f_times_out did not complete!\n";
}
std::cout << "Done!\n";
}
输出
返回结果
T get(); (1) (仅为泛型 future 模板的成员) (C++11 起)
T& get(); (2) (仅为 future<T&> 模板特化的成员) (C++11 起)
void get();(3) (仅为 future<void> 模板特化的成员) (C++11 起)
get
方法等待直至 future
拥有合法结果并(依赖于使用哪个模板)获取它。它等效地调用 wait() 等待结果。
泛型模板和二个模板特化各含单个 get
版本。 get
的三个版本仅在返回类型有别。
若调用此函数前 valid() 为 false 则行为未定义。
释放任何共享状态。调用此方法后 valid() 为 false 。
参数
(无)
返回值
1) 存储于共享状态的值 v
,如同 std::move(v) 。
2) 存储于共享状态的值的引用。
3) 无。
异常
若 future 所引用的共享状态中存储异常(例如,通过调用 std::promise::set_exception() ),则抛出该异常。
注意
鼓励实现在调用前检测 valid() 为 false 的情况,并抛出以 std::future_errc::no_state 为 error_condition 的 std::future_error 。
调用示例
#include <thread>
#include <future>
#include <iostream>
#include <string>
#include <chrono>
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()
{
{
std::cout << time() << " launching thread\n";
std::future<int> f = std::async(std::launch::async, []
{
std::this_thread::sleep_for(std::chrono::seconds(1));
return 7;
});
std::cout << time() << " waiting for the future, f.valid() == "
<< f.valid() << "\n";
int n = f.get();
std::cout << time() << " future.get() returned with " << 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(std::chrono::seconds(1));
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() << " future.get() returned with " << n
<< " f.valid() = " << f.valid() << '\n';
}
catch (const std::exception& e)
{
std::cout << time() << " caught exception " << e.what()
<< ", f.valid() == " << f.valid() << "\n";
}
}
}
输出