(オリジナル)c++11 function/lamdaのチェーンコール

5323 ワード

チェーン呼び出しについては、比較的典型的な例はc#のlinqであるが、c#のlinqは特定の関数のチェーン呼び出しにすぎない.c++のチェーン呼び出しは、実装が複雑であるため、よりまれである.c++11はlamdaとfunctionをサポートし、いくつかの遅延計算のシーンでは、このチェーン呼び出しの需要がより強くなった.チェーン呼び出しを実現する目的は、複数の関数を前の出力に従って次の入力として直列に接続し、ある時点に延期して計算することである.c++では,現在PPLにこのような使い方が見られる.PPLにおけるチェーン呼び出しの例:
int wmain()
{
    auto t = create_task([]() -> int
    { 
        return 0;
    });

    // Create a lambda that increments its input value.
    auto increment = [](int n) { return n + 1; };

    // Run a chain of continuations and print the result.
    int result = t.then(increment).then(increment).then(increment).get();
    wcout << result << endl;
}

/* Output:
    3
*/

例ではtaskオブジェクトを作成し、then関数を連続的に呼び出すが、このthenのlamdaのパラメータは、前の関数の出力が後の入力であることを保証すれば任意のタイプであってもよい.これらのtaskを直列に並べた後,最後に必要なときに結果を計算し,計算の過程はチェーン式であり,最初の関数から最後の関数まで計算して最終結果を得る.このtaskと彼のチェーン呼び出しプロセスは興味深い.しかし、PPLのチェーン呼び出しは、wait関数がパラメータを受信できないため、初期化されたtaskにパラメータがあることができません.探索を経て、c++11で差の少ないチェーン呼び出しのtaskを作ることができて、前に言ったPPL taskがあまりよくないところを補うことができて、つまりパラメータを受信することができます.実はチェーン呼び出しの実現について私は前にブログで紹介しましたが、興味のある子供ここをクリックです.しかし、私は以前の実現方式にあまり満足していません.PPLというチェーン呼び出し方式のほうがいいと思います.では、pplと似たようなチェーン呼び出しのtaskを実現する方法を見てみましょう.
template<typename T>
class Task;

template<typename R, typename...Args>
class Task<R(Args...)>
{
public:
    Task(std::function<R(Args...)>&& f) : m_fn(std::move(f)){}

  Task(std::function<R(Args...)>& f) : m_fn(f){}
template<typename... Args> R Run(Args&&... args) { return m_fn(std::forward<Args>(args)...); } template<typename F> auto Then(F& f)->Task<typename std::result_of<F(R)>::type(Args...)> { return Task<typename std::result_of<F(R)>::type(Args...)>([this, &f](Args&&... args){
      return f(m_fn(std::forward<Args>(args)...)); }); } private: std::function<R(Args...)> m_fn; };

テストコード:
void TestTask()
{
  Task<int(int)> task = [](int i){return i;};
  auto result = task.then([](int a){return i+1;}).then([](int a){return i+2;}).then([](int a){return i+3;}).run(1);
  //result 7
}

私のTask呼び出し方式はPPLと一致しており、さらに素晴らしいのはパラメータを受信することもできます.チェーン呼び出しというものが本当に役に立つのか疑問に思っている人もいるかもしれません.少なくとも現在PPLとTBBがこのように使われているのを見て、彼は私の開発にとって非常に役に立ち、私が彼の具体的な応用についてはしばらく表を押さないと、後で私がどのようにそれを使うか知っています.
この文章があなたに役に立つと思ったら、お勧めをクリックしてください.ありがとうございます.
c++11 boost技術交流群:296561497、技術交流へようこそ.