最終更新日時: 2026年01月29日 13時22分36秒 (JST)
Akira Takahashi が更新

履歴 編集

function
<future>

# std::packaged_task::コンストラクタ(C++11)

    packaged_task() noexcept;                          // (1)

    template <class F>
    explicit packaged_task(F&& f);                     // (2)

    template <class F, class Allocator>
    explicit packaged_task(allocator_arg_t,
                           const Allocator& a, F&& f); // (3) C++17で削除、C++26で再追加

    packaged_task(packaged_task&) = delete;            // (4) C++11
    packaged_task(const packaged_task&) = delete;      // (4) C++14

    packaged_task(packaged_task&& rhs) noexcept;       // (5)

## 概要

- (1) : デフォルトコンストラクタ。
- (2) : 関数オブジェクトを受け取るコンストラクタ。
- (3) : 関数オブジェクトおよびカスタムアロケータを受け取るコンストラクタ。
- (4) : コピーコンストラクタ。コピー不可。
- (5) : ムーブコンストラクタ。

## 効果

- (1) : 共有状態なし、タスクの保持なしでオブジェクトを構築する。
- (2) : 共有状態を初期化し、`f`を非同期実行するタスクとして`std::forward<F>(f)`でメンバ変数に保持する。
- (3) : 共有状態を初期化し、`f`を非同期実行するタスクとして`std::forward<F>(f)`でメンバ変数に保持する。アロケータ`a`は、共有状態を構築する際に、その内部構造でメモリ確保が必要な場合に使用される。
- (5) : `rhs`の共有状態の所有権、および非同期タスクの関数オブジェクトを`*this`に移動する。

## 例外

- (2) : `F`のコピーコンストラクタもしくはムーブコンストラクタによって送出されうる、あらゆる例外が投げられる可能性がある。
- (3) : `F`のコピーコンストラクタもしくはムーブコンストラクタによって送出されうる、あらゆる例外が投げられる可能性がある。内部構造のメモリ確保に失敗した場合、`std::bad_alloc`が投げられる。

## 事後条件

- (5) : `rhs`は共有状態を持たない

## 備考

- (2), (3) :
  - C++14 : `std::remove_cvref<F>::type`が`std::packaged_task<R(ArgTypes...)>`型である場合、この関数はオーバーロード解決に参加しない。

## 例

    #include <memory>
    #include <future>
    #include <utility>

    int foo() { return 3; }

    int main()
    {
      // デフォルト構築
      // 共有状態とタスクを持たない
      {
        std::packaged_task<int()> task;
      }

      // 関数オブジェクトを受け取って構築
      // 共有状態の初期化、およびタスクを内部に保持する
      {
        std::packaged_task<int()> task(foo);
      }

      // 関数オブジェクトとアロケータを受け取って構築
      // 共有状態をアロケータを使用して初期化子、タスクを内部に保持する
      {
        std::packaged_task<int()> task {
            std::allocator_arg,
            std::allocator<std::packaged_task<int()>>(),
            foo
        };
      }

      // ムーブ構築
      // 共有状態の所有権とタスクを移動する
      {
        std::packaged_task<int()> task1(foo);
        std::packaged_task<int()> task2 = std::move(task1);

        // task1は共有状態を持たない
      }
    }

### 出力

## バージョン

### 言語

- C++11

### 処理系

- Clang: ??
- GCC: 4.7.0 ✅
- ICC: ??
- Visual C++: 2012 (11.0はアロケータを引数に取るものがコンパイルできない？) ✅

## 参照

- LWG Issue 2067. `packaged_task` should have deleted copy c'tor with const parameter
- LWG Issue 2097. `packaged_task` constructors should be constrained
- LWG Issue 2921. `packaged_task` and type-erased allocators
  - `std::function`のコンストラクタと同様の理由により、アロケータを受け取るコンストラクタを削除
- LWG Issue 3039. Unnecessary `decay` in `thread` and `packaged_task`
- P3503R3 Make type-erased allocator use in `promise` and `packaged_task` consistent
  - C++26でアロケータを受け取るコンストラクタを再追加