c++algorithmfor-loopautostd

How to have a auto for loops, alternative to nested for loops?


I am wondering if there is something available in C++ which helps us to iterate over the two nested loops while using auto. Say like, I would want to compare an array element with all other elements forward. This is how we do it traditionally:

std::vector<int> vec {1, 2, 3, 4};

for (int i = 0; i < vec.size(); ++i) 
{
    for (int j = i + 1; j < vec.size(); ++j) 
    {
        if (vec[i] == vec[j]) {}
        // Compares 1 with 2, 3 and 4
        // Compares 2 with 3 and 4
    }
}

The intention is to use auto in order to achieve this.

std::vector<int> vec{1, 2, 3, 4};

for (<auto>& i : vec)
//   ^^^^^^^
{
    // What should I write here so that I compare only the forward elements?
}

We can probably use something like this:

for (auto it = vec.begin(); it != vec.end(); ++it)
{
    for (auto jt = it + 1; jt != vec.end(); ++jt) 
    {
        // Do a comparison here.
    }
}

And the third snapshot again writes more code. I am looking to get more insights on the plain second snapshot.

Mentioned in the question itself.


Solution

  • I am wondering if there is something available in C++ which helps us to iterate over the two nested loops while using auto.

    Not exactly what you wished for; However, with std::ranges::iota_view (Since ), you could write nested range-based for loops like follows:

    #include <ranges> // std::ranges::iota_view
    
    for (const auto i : std::views::iota(0u, std::size(vec)))
    {
        for (const auto j : std::views::iota(i + 1u, std::size(vec)))
        {
            if (vec[i] == vec[j])
            {
                // .....
            }
        }
    }
    

    See a live demo in godbolt.org

    Additionally, this enables you to have i and j be const over the loop scope.


    Side note: For compilers older than C++20, one could easily implement an iterator that act exactly like std::ranges::iota_view.