3

ツリーデータ構造とそれにいくつかの操作を実装しています。すべてのノードには、いくつかの値、その親へのポインター、およびその子のリストがあります。ツリーを再帰的に移動し、ノードに格納されている最大値を見つける関数max_valueを実装しました。ここで、C ++ 11標準を使用して、同じことを行う非同期関数を実装したいと思います。私は次のコードを持っています:

template<typename T>
T Node<T>::max_value_async(void)
{
    T current_value = p_value;
    list<future<T>> results;
    //launch tasks
    for ( auto x : p_children)
    {
        results.insert(async(std::launch::async, x.max_value));
    }
    //wait for results
    for (auto r : results)
        r.wait();
    //find highest value
    for (auto r : results)
    {
        if (current_value < r.get())
            current_value = r.get();
    }

    return current_value;
}

しかし、非同期機能を起動するのに問題があります。どうしたの?

4

1 に答える 1

5

いくつかの問題があります:

  • wait()まず、それはによって暗示されるので、使用する必要はありませんget()
  • listまたはで正常vectorに動作しpush_backます。に間違った数の引数を指定しましたlist::insert。最適なのは、インプレース構造を使用することですemplace_back
  • また、.get()一度だけ行うべきだと思われます。後続の呼び出しは例外をget()生成しstd::future_errorます。
  • 先物を構築するために使用した構文は存在しません。そのようなことを行う最も簡単な方法は、以下のようにラムダを使用することです。

完全な例:

// g++ -pthread -std=c++0x 
#include <iostream>
#include <future>
#include <list>

struct X {
  X(int v) : mv(v) {}
  int mv;
  int max_value() const {
    return mv;
  }
};

int main(){
  std::list<std::future<int> > results;
  X x4(4);
  X x5(5);
  X x3(3);

  results.emplace_back(std::async(std::launch::async, 
    [&x4](){ return x4.max_value();}));
  results.emplace_back(std::async(std::launch::async, 
    [&x5](){ return x5.max_value();}));
  results.emplace_back(std::async(std::launch::async, 
    [&x3](){ return x3.max_value();}));

  // for sure there's better ways to do this step, but for clarity:
  int best_value=0;
  for (auto &r : results){
      auto this_value=r.get();
      if (best_value < this_value)
        best_value = this_value;
    }

  std:: cout << best_value << std::endl;
}

共有ポインターを使用するため、ラムダにオブジェクトを値で取得させることもできます。

std::shared_ptr<SomeT> some_obj= ... from somewhere... ;
results.emplace_back(
   std::async(
     std::launch::async, [some_obj](){ return some_obs->max_value();}
   )
);
于 2012-10-27T10:15:15.293 に答える