【问题标题】:C++ passing vector of unique_ptrs as parameters to corresponding element of another equal-length vector (especially parallelly)C++ 将 unique_ptrs 的向量作为参数传递给另一个等长向量的对应元素(尤其是并行)
【发布时间】:2012-01-15 10:09:12
【问题描述】:

我有:

  • ObjectA 的unique_ptrs 的向量

  • ObjectB的新默认构造向量的向量,和

  • 对象 B 中具有签名 void f(unique_ptr<ObjectA> o) 的函数。

(此处省略词对象)

我如何为所有0 < i < length 并行处理Bvec[i].f(Avec[i])

我尝试过使用transform(Bvec.begin(), Bvec.end(), A.begin(), B.begin(), mem_fun_ref(&B::f)),但它给出了一堆错误,我不确定它是否会传递正确的 A 作为参数,更不用说让我移动它们了。 (&B::f(A.begin()) 也不能作为最后一个参数。

我也想过使用 for_each 和 lambda 函数,但不知道如何获取相应的元素。我想增加一个计数器,但我认为并行化不好(我可能错了)。

当然,我可以使用从 0 到结束的 for 循环,但我很确定我缺少一个简单的东西,它与简单的 for 循环不平行。

谢谢。

【问题讨论】:

  • 您意识到,通过传递一个唯一的指针,您正在将这些指针的所有权从列表中转移到该函数中,对吗?此外,它也不与std::transform 并行。
  • @NicolBolas 是的,我进行了传输,但不,我不知道转换不是并行完成的......谢谢。 (MTG 播放器?题外话,纳米)
  • 并行是指并发吗? transform 将像所有其他 stdlib 算法一样按顺序工作。此外,transform 永远不会起作用,因为它需要一个返回某些东西的函子。
  • @pmr 是的,我猜同时。我可以在我的脑海中看到 2 行框,其中有一个箭头从一行指向另一行,这应该很容易同时完成,对吧?
  • 不,也不一定比按顺序做要快。这完全取决于f 中完成的工作量。

标签: c++ vector c++11 parallel-processing unique-ptr


【解决方案1】:

这是一个使用手工算法的非并行实现。我敢肯定,更精通functional 的人可以提出更优雅的解决方案。 transform 的问题在于,我们不能将它与返回 void 的函数一起使用,而且我不记得另一个 stdlib 函数需要两个范围并将它们相互应用。如果你真的想并行化这个,它需要在apply_to 函数中完成。启动async 任务(例如std::async(*begin++, *begin2++) 可以工作,虽然我没有这方面的经验并且无法让它在 gcc 4.6.2 上工作。

#include <iterator>
#include <memory>
#include <vector>
#include <algorithm>
#include <functional>


// this is very naive it should check call different versions
// depending on the value_type of iterator2, especially considering
// that a tuple would make sense
template<typename InputIterator1, typename InputIterator2>
void apply_to(InputIterator1 begin, InputIterator1 end, InputIterator2 begin2) {
  while(begin != end) {
    (*begin++)(*begin2++);
  }
}

struct Foo {

};

struct Bar {
  void f(std::unique_ptr<Foo>) { }
};


int main()
{
  std::vector< std::unique_ptr<Foo> > foos(10);
  std::vector< Bar > bars(10);
  std::vector< std::function<void(std::unique_ptr<Foo>) > > funs;

  std::transform(bars.begin(), bars.end(), std::back_inserter(funs),
                 // non-const due to f non-const, change accordingly
                 [](Bar& b) { return std::bind(&Bar::f, &b, std::placeholders::_1); });

  // now we just need to apply each element in foos with funs
  apply_to(funs.begin(), funs.end(), std::make_move_iterator(foos.begin()));


  return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    相关资源
    最近更新 更多