91271
##### 目的

C++のcreate_taskを使用しています。  
外から渡すデータをcopyではなくmoveさせたい。

##### 質問

create_taskに渡す際に、コピーを発生させないようにstd::move動作させると、１回ムーブ後に、複数回コピーコンストラクタが実行されます。  
別質問にて、create_taskのラムダがコピーされているのでコピーが発生していると教えていただいたのですが、しかし１回はともかく、複数回は多いです。これはどうしようもないでしょうか？

```

    struct Test
    {
      std::unique_ptr<int[]> data; // データ
      int value;
    
      Test(std::unique_ptr<int[]>&& d)
        : data(std::forward<std::unique_ptr<int[]>>(d))
        , value(10)
      {
      }
    
      Test(const Test& _obj)
      {
        value = _obj.value;
        ::OutputDebugStringW(L"コピー\n");
      }
    
      Test(Test&& _obj) noexcept
        : data(std::forward<std::unique_ptr<int[]>>(_obj.data))
        , value(_obj.value)
      {
        ::OutputDebugStringW(L"ムーブ\n");
      }
    };
    
    int main()
    {
      std::unique_ptr<int[]> data = std::make_unique<int[]>(10);
      Test sample(std::move(data));
      std::vector<Test> List;
      List.emplace_back(std::move(sample));
      pplx::create_task([test_c = std::forward<std::vector<Test>>(List), 10]()
      { 
      });
      List.clear();
    }
    
```
CC BY-SA 4.0
2022-09-24T02:21:15.200
91270
2022-09-26T10:26:41.813
2022-09-26T10:26:41.813
54485
54485
question
c++
create_taskに変数を渡す際にコピーを発生させたくない。
`pplx::create_task`を簡単に説明している [Programming with
Tasks](https://github.com/microsoft/cpprestsdk/wiki/Programming-with-Tasks)
の末尾にちょろっとリンクがありますが、`pplx::create_task`の元ネタとなった [タスクの並列化 (コンカレンシー
ランタイム)](https://learn.microsoft.com/ja-jp/cpp/parallel/concrt/task-
parallelism-concurrency-runtime?view=msvc-170) が参考になるかと思います。

> 一般的なパターンは、継続のチェーンの 1 つのタスクが変数に割り当てられ、別のタスクがその変数を読み取る場合です。
> 各継続タスクが変数のそれぞれのコピーを保持するため、値によるキャプチャができません。
> スタック割り当て変数においても、変数が有効でなくなる場合があるため、参照によるキャプチャができません。
>
> この問題を解決するには、std::shared_ptr などのスマート ポインターを使用し、変数をラップして、スマート ポインターを値で渡します。
> この方法を使用すると、基になるオブジェクトが割り当てられ、読み込むことができ、それを使用するタスクのために十分な有効期間となります。

と`std::shared_ptr`の利用が提案されています。（`std::unique_ptr`でなく）`std::shared_ptr`でオブジェクトを保持した場合、`std::shared_ptr`そのものはコピーされますが、保持したオブジェクトはコピーもムーブもされないため、今回の要件を満たすかと思います。
CC BY-SA 4.0
2022-09-24T02:38:42.777
91271
2022-09-24T02:38:42.777
4236
91270
answer