У меня есть параллельный код, который можно сократить до:
#include <algorithm>
#include <vector>
struct TKeyObjPtr;
class TObj
{
public:
virtual void Calculate(TKeyObjPtr const &) = 0;
};
struct TKeyObjPtr
{
int Key;
TObj *ObjPtr;
};
void Calculate(std::vector<TKeyObjPtr> const &KeyObjPtrVec)
{
#pragma omp parallel for
for (auto It1= KeyObjPtrVec.begin(); It1!=KeyObjPtrVec.end(); ++It1)
for (auto It2= It1+1; It2!=KeyObjPtrVec.end() && It2->Key==It1->Key; ++It2)
It1->ObjPtr->Calculate(*It2);
}
Я бы хотел модернизировать этот код с помощью параллельных алгоритмов c ++ 17 .К сожалению, у меня возникают проблемы при переписывании такого простого куска кода.
Можно использовать параметр boost::counting_iterator
:
void Calculate(std::vector<TKeyObjPtr> const &KeyObjPtrVec)
{
std::for_each(std::execution::par_unseq,
boost::counting_iterator<std::size_t>(0u),
boost::counting_iterator<std::size_t>(KeyObjPtrVec.size()),
[&KeyObjPtrVec](auto i)
{
for (auto j= i+1; j<KeyObjPtrVec.size() && KeyObjPtrVec[j].Key==KeyObjPtrVec[i].Key; ++j)
KeyObjPtrVec[i].ObjPtr->Calculate(KeyObjPtrVec[j]);
});
}
Это работает, нозначительно более многословный и, что еще хуже, я не думаю, что он соответствует стандарту, потому что boost::counting_iterator
является итератором хранения и, следовательно, не соответствует Cpp17ForwardIterator требованиям .
Можно ли написать приведенный выше код так же лаконично, как с OpenMP, при соблюдении ограничений стандарта на параллельные алгоритмы?