4

これは、Microsoft C++ Concurrency API のコンテキストにあります。

agent(名前空間の下に)と呼ばれるクラスがありConcurrency、それは基本的に純粋な仮想を派生させて実装するステートマシンですagent::run

ここで、実行可能なagent::start状態にするを呼び出すのはあなたの責任です。次に、* またはそのバリアントのいずれかを呼び出して、メソッドを実際に実行します。agent::waitagent::run

しかし、なぜagent::done体内で呼び出さなければならないのでしょうか? つまり、明らかな答えは、agent::wait* は完了が通知されるか、タイムアウトが経過するまで待機するということですが...

設計者は何を意図していたのですか?agent::run戻ったときにエージェントを完了状態に入れないのはなぜですか? それが私が知りたいことです。電話をかけないという選択肢があるのはなぜdoneですか? タイムアウトが経過すると、待機メソッドは例外をスローします。

4

1 に答える 1

2

私が見ることができる唯一の理由は、それがあなたにあなたがいることを述べさせdone()、そしてあなたがあなたの消費者に待たせたくないより多くの仕事(例えば、クリーンアップ)をすることを可能にするということです。

今、彼らはこれを行うことができたでしょう:

private: void agent::do_run() {
  run();
  if (status() != agent_done)
    done();
}

次に、直接(または同等のもの)do_run()ではなく、フレームワークを呼び出します。run()

ただし、これは自分で実行できることに注意してください。

class myagent: public agent {
protected:
  virtual void run() final override { /* see do_run above, except call do_run in it */ }
  virtual void do_run() = 0;
};

とpoof、あなたdo_run()が呼び出すのに失敗した場合done()、ラッピング関数はあなたのためにそれを行います。この2番目の仮想関数のオーバーヘッドが高すぎる場合:

template<typename T>
class myagent: public agent {
private:
  void call_do_run()
  {
    static_cast<T*>(this)->do_run();
  }
protected:

  virtual void run() final override { /* see do_run above, but call_do_run() */ }
};

コンパイル時のディスパッチを可能にするCRTP。使用する:

class foo: public myagent<foo>
{
public:
  void do_run() { /* code */ }
};

.../肩をすくめる

于 2012-11-16T19:14:35.583 に答える