C++ is there another way to access members first and second than using a range for loop for std::vector <std::pair <int, int>>?

Viewed 184

I solved another problem the other day involving a std::vector <std::pair<int,int>> called name.

My question is, how do I access the name.first and name.second of this type?

I ended up using a ranged-for loop, that solved my issue

for(i : name) { i->first , i->second}

But, is there another way? I am particularly interested in how to access this in a normal for loop, e.g

for(int i = 0; i < name.size(); i++) { std::vector::std::pair::name.first}

Can anybody shed some light on this for me?

7 Answers

In C++17, you can use a structured binding

for (auto & [a, b] : name) {
    // a is a reference to the first of each pair
    // b is a reference to the second of each pair
}

The usual way

for (size_t i = 0; i < name.size(); i++)
{
     cout << name[i].first;
     cout << name[i].second;
}

This is just the typical way to access a vector (or array) of structs.

BTW the code you said worked in fact does not, for(i : name) { i->first , i->second} should be for(i : name) { i.first , i.second}. Your version would work for a vector of pair pointers, but not for a vector of pairs.

As of C++17, you can use structured bindings:

#include <iostream>
#include <vector>
#include <tuple>

int main() {
    std::vector<std::pair<int,int>> v{};
    v.push_back({1, 11});
    v.push_back({2, 22});
    for (auto [a, b] : v) {
        std::cout << a << " " << b << "\n";   
    }  // 1 11
       // 2 22
}

Note that auto in the structured binding declaration means each pair is taken by value (which is reasonable when working with fundamental types).

If you want to either read a non-fundamental type, or write via structured binding identifier, you may use auto const& or auto&, respectively. E.g.:

// add 'first' to 'second;
for (auto& [a, b] : v) {
    b += a;  
}  // 1 11
   // 2 22

// read only (by value)
for (auto [a, b] : v) {
    std::cout << a << " " << b << "\n";   
}  // 1 12
   // 2 24

There's also structured bindings:

#include <iostream>
#include <vector>
#include <utility>

int main()
{
    std::vector<std::pair<int, int>> somePairs{ {1, 2}, {5, 10}, {12, 60} };

    for (auto [first, second] : somePairs)
    {
        std::cout << "First = " << first << ", second = " << second << '\n';
    }

    return 0;
}

This automatically unpacks the std::pairs inside the std::vector into the first and second variables.

Output:

First = 1, second = 2
First = 5, second = 10
First = 12, second = 60

This is a very basic question about C++ syntax. I recommend a book instead of Stack Overflow.

The elegant way to do this is:

std::vector<std::pair<int, int>> names;
for(int i = 0; i < names.size(); i++) {
    auto &name = names[i];
    // now access name.first, name.second
}
unordered_map<int , int> mp;
for(auto x:mp)
{

    cout<<x.first;
    cout<<x.second;
}

This is the way you can access members first and second in a standard template library (STL) by creating a container with key-value and a mapped value with unique pair.

Related