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要么vectorpush_back. 您给 . 的参数数量错误list::insert。最好是使用就地施工emplace_back
  • 看来你应该只做.get()一次。后续调用get()产生std::future_error异常。
  • 您用于构建期货的语法不存在。做这样的事情的最简单方法是使用如下的 lambda。

完整示例:

// 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;
}

由于您使用共享指针,您还可以使 lambda 按值获取对象,

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 回答