-1

I wanted to get the index of the value(s) inside std algorithm's lambda function. So that, I can perform computation on the values based on the index. I am able to get an index with for_each function. However, I am not able to do so for std::adjacent_difference. Can you help me understand why I am not able to extract the index in other algorithms that use binary op? My attempt is to try in a generic fashion that work on a parallel (thrust) setting as well. So, did not seek a method of static count'ing.

//~~~START:Mon, 04-Oct-2021, 13:03:46 IST
//~~~Author:Rajesh Pandian M | mrprajesh.co.in
#include <bits/stdc++.h>
void print(const auto &data){
  std::copy(data.begin(),data.end(), std::ostream_iterator<int>(std::cout, " "));
  std::cout << '\n';
}
int main(int argc, char* argv[]){

  std::vector<int> data={0,2,3,5,10,11};
  std::for_each(data.begin(), data.end(), [&data](int const& value) {
    int idx = &value - &data[0];
    std::cout<< "idx: " << idx << '\n';
  });

  print(data);

  std::vector<int> result(data.size());
  std::adjacent_difference(data.begin(), data.end(), result.begin(),
    [&data]( const int& value2, const int& value1) {
      int idx = &value2 - &data[0];
      std::cout<< "idx: " << idx << '\n';
      return value2-value1; //Some expression involving index, values[1,2]
    });

  print(result);

  return 0;
}

Outputs:

idx: 0
idx: 1
idx: 2
idx: 3
idx: 4
idx: 5
0 2 3 5 10 11 
idx: -102822055
idx: -102822055
idx: -102822055
idx: -102822055
idx: -102822055
0 2 1 2 5 1 

mrprajesh
  • 31
  • 1
  • 7
  • 1
    [This](https://stackoverflow.com/q/65022698/10107454) could be of interest. – paleonix Oct 07 '21 at 08:48
  • As this question is tagged with Thrust: Thrust provides some smart iterators to solve this problem. There is a `thrust::counting_iterator` similar to what was implemnted in the question I linked above. There is also the `thrust::zip_iterator` to combine the counting iterator with e.g. the iterator to a container when the algorithm doesn't take enough inputs. – paleonix Oct 07 '21 at 09:00

1 Answers1

1

From cppreference/adjacent_difference:

First, creates an accumulator acc whose type is InputIt's value type, initializes it with *first, and assigns the result to *d_first. Then, for every iterator i in [first + 1, last) in order, creates an object val whose type is InputIt's value type, initializes it with *i, computes val - acc (until C++20) val - std::move(acc) (since C++20) (overload (1)) or op(val, acc) (until C++20) op(val, std::move(acc)) (since C++20) (overload (3)), assigns the result to *(d_first + (i - first)), and move assigns from val to acc.

In short: The binary operator is called via op(val,acc) and neither val nor acc are elements of the container.

If you need the index you can populate a std::vector<std::pair<size_t,int>> such that data[ i ].first == i.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185