Как использовать Итератор при указании политики выполнения std::execution::par
для алгоритма STL, такого как std::for_each
?
В приведенном ниже примере я хочу взять квадратный корень из диагонали матрицы Eigen3 следующим образом:
template<typename T>
using Matrix = Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
template<typename T>
std::vector<T> getStdDev(const Matrix &x) const {
const size_t len = x.rows();
std::vector<T> stdDev(len);
// Generate indices.
size_t idx = 0;
std::vector<size_t> indices(len);
auto ind = [&idx]() {
return idx++;
};
std::generate(indices.begin(), indices.end(), ind);
// Take square root of diagonal elements.
auto sr = [&x](size_t i) {
stdDev[i] = std::sqrt(x(i, i));
};
std::for_each(std::execution::par, indices.begin(), indices.end(), sr);
return stdDev;
}
Насколько мне известно, приведенный выше код потокобезопасен . Однако как можно достичь такого же эффекта с помощью итератора в поточно-ориентированном режиме , не генерируя сначала нужные индексы, как описано выше? Предполагается, что в контейнере, для которого выполняется итерация, не реализован итератор, или нет итератора, поточно-безопасного .
В идеале я хотел бы сделать это в общем (я знаю, что у Эйгена есть итераторы, он используется здесь только в качестве примера).
Кроме того, было бы крайне предпочтительно использовать только функции C ++ (без библиотек, но без стандарта).