Search code examples
c++predicatestd

How do I find the index of the element being passed to the predicate in STL functions?


Consider the following piece of code:

    std::vector<int> vec(n);
    for (auto& elem : vec) {
        std::cin >> elem;
    }
    auto count = 0;
    while (!isGood(vec)) {
        auto odd_it = std::find_if(vec.begin(), vec.end(), [] (int num) { return ~(num % 2); });
        auto even_it = std::find_if(vec.begin(), vec.end(), [] (int num) { return num % 2; });
        if(odd_it != vec.end() && even_it != vec.end()) {
            std::swap(vec.at(std::distance(vec.begin(), odd_it)), vec.at(std::distance(vec.begin(), even_it)));
            count++;
        }
        else {
            count = -1;
            break;
        }
    }

(I know its not the entire code, but its enough to recreate the problem)

In this code, the line auto odd_it (and also auto even_it) will return me the first odd element in the vector. However, I wanted the std::find_if to return me an iterator pointing to the first odd element which also has an even index (which in this case coincidentally happens to also be the first odd element too.)

So, in a nutshell, the question is basically to find the index of the element currently being "worked upon" by the function (which has been passed to the predicate)


Solution

  • The most clear solution in C++17 and below is simply to write your own version of find_if that passes an index to the predicate. The implementation is straightforward:

    template<class Input_it, class Predicate>
    Input_it find_if_with_index(Input_it first, Input_it last, Predicate p) {
        for (std::size_t i = 0; first != last; ++i, ++first) {
            if (p(i, *first))
                return first;
        }
        return last;
    }