- future[meta header]
- std[meta namespace]
- packaged_task[meta class]
- function[meta id-type]
- cpp11[meta cpp]
void operator()(ArgTypes... args);タスクの実行し、戻り値を共有状態に格納する。
メンバ変数として保持している関数オブジェクトfに対してINVOKE(f, args..., R)によって関数呼び出しを行い、その戻り値をfutureとの共有状態に格納する。関数fの内部で例外が送出された場合は、共有状態に送出された例外が格納される。
共有状態が準備完了状態(future_status::ready)となる。
なし
この関数は、以下のerror conditionを持つfuture_error例外オブジェクトを送出する可能性がある:
promise_already_satisfied: 格納されたタスクがすでに実行されたno_state:*thisが共有状態を持っていない(packaged_taskオブジェクトがムーブされると起こりうる)
#include <iostream>
#include <future>
#include <stdexcept>
int plus_task(int a, int b)
{
return a + b;
}
int except_task()
{
throw std::runtime_error("error!");
}
int main()
{
{
std::packaged_task<int(int, int)> task(plus_task);
std::future<int> f = task.get_future();
// タスクを実行する
task(2, 3);
// タスクの結果を取得
int result = f.get();
std::cout << result << std::endl;
}
// 例外を投げるタスク
{
std::packaged_task<int()> task(except_task);
std::future<int> f = task.get_future();
// タスクを実行する
task();
// タスクの結果を取得
try {
f.get();
}
catch (std::runtime_error& e) {
// タスク内で送出された例外を捕捉
std::cout << e.what() << std::endl;
}
}
}- task(2, 3);[color ff0000]
- task()[color ff0000]
- std::runtime_error[link /reference/stdexcept.md]
- task.get_future()[link get_future.md]
- std::future[link /reference/future/future.md]
- f.get()[link /reference/future/future/get.md]
5
error!
- C++11
- Clang: ??
- GCC: 4.7.0 [mark verified]
- ICC: ??
- Visual C++: 2012 [mark verified]
- LWG Issue 2008. Conflicting Error Conditions for
packaged_task::operator()- C++11で、
promise_already_satisfiedを送出する条件が「共有状態がすでに準備完了である」から「格納されたタスクがすでに実行された」へ改められた。前者では、タスクの実行完了前に共有状態が準備完了になる状況と条件が食い違っていた
- C++11で、
- LWG Issue 2142.
packaged_task::operator()synchronization too broad?- C++14で、この関数についての同期の規定が削除された。「
futureやshared_futureのあらゆるメンバ関数の呼び出しと同期する」という規定は、タイムアウトで戻るwait_for()やwait_until()まで含んでしまい広すぎたため。共有状態そのものの規定で必要な同期は既に保証されている
- C++14で、この関数についての同期の規定が削除された。「