jeudi 31 août 2023

Replace handwritten for loop in C++ when index has to be accessed inside lambda

I am trying to replace the hand written for loop in using_for_loop() by algorithm methods. no_for_loop() is the version that would replace using_for_loop(). Any clue on how to implement the lambda? In general, for a vector of vectors how to iterate the inner for loop in the lambda or a function object. It would require access to the outer loop index. If I were to use std::distance() to compute the index inside the lambda, I would need access to the the iterator. But I have only the value/object inside passed to the lambda. Is there is a way to pass the iterator to the lambda?
The motivation is to follow the suggestion made by the book Effective STL: 50 Specific Ways to Improve Your Use of the Standard Template Library by Scott Meyers. One of them is Item 43: Prefer algorithm calls to hand-written loops

Note: In the real program "vec" is the inputs. I made it local and added assign_vec(10'000'000,vec); call to make it stand alone.

#include <algorithm> 
void assign_vec(const int64_t &count, std::vector<std::array<int64_t, 3>> &v)
{
  for (int i = 0; i < count;++i)
  {
    std::array<int64_t, 3 > a{i,i+1,i+2};
    v.emplace_back(a);
  }
}

int using_for_loop() {
  std::vector<std::array<int64_t, 3>> vec;
  assign_vec(10'000'000,vec);
  size_t k{};
  for (auto i = (size_t)0, n = vec.size(); i < n; )
  {
    auto j = i + (size_t)1;
    for (; j < n; ++j)
    {
      if (vec[i][0] != vec[j][0] || std::minmax(vec[i][1], vec[i][2]) != std::minmax(vec[j][1], vec[j][2]))
        break;
    }

    if (i + (size_t)1 == j)
      vec[k++] = vec[i];

    i = j;
  }
  vec.resize(k);
  return 0;
}

int no_for_loop() {
  std::vector<std::array<int64_t, 3>> vec;
  assign_vec(10'000'000, vec);
  size_t k{};
  //??std::for_each(std::begin(vec), std::end(vec), []() {});
  vec.resize(k);
  return 0;
}

Aucun commentaire:

Enregistrer un commentaire